算法基础之排序算法[图文]

文章脉络算法

        

算法编程

   什么是算法?性能

    算法是解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法表明着用系统的方法描述解决问题的策略机制。 排序算法就是对排序的一种解决方案;而查找算法就是对查找的解决方案。spa

   算法用来干什么?.net

    提升计算机速度并节省存储空间一直成为编程人员努力的方向,排序操做成为程序设计人员考虑的因素之一,排序方法选择得当与否直接影响程序执行的速度和辅助存储空间的占有量,进而影响整个软件的性能。设计

    此处省略2000字……指针

排序算法对象

    所谓排序就是把一组无序序列按照关键字有序的排列起来。在待排序的数据中,若是存在多个相同关键字,通过排序后这几个相同关键字的相对次序不变,则该排序时稳定的;不然为不稳定的,以下图:blog

            

    如下不单独说明都以正序排序为例(从小到大)。排序

插入排序

    插入排序的基本思想是从待排序中拿出一个元素,而后逐个拿出一个元素,与当前元素比较,插入到合适的位置,直到所有插入完毕为止。

    直接插入排序

    直接排序在插入第i个元素时,R1R2……Ri-1已经排好序,将第i个元素依次与R1Ri-1比较,找到合适位置。直接排序要进行n-1趟排序。

    以数字1-7打乱顺序后排序为例:

        希尔排序

    希尔排序时对直接插入排序的升级版,我认为希尔排序的升级在于:先利用步长将元素分组,组内排序完毕后;再从新用步长分组,再排序,直到完整排序,实质是分组插入方法。

    仍然以被打乱的7个数字为例(相同颜色连线为一组):

选择排序

    选择排序的基本思想是从带排序的元素中,选出最小的记录,让后顺次排下去。

    直接选择排序

    仍然以被打乱的7个数字为例:

            

    堆排序

    堆排序的基本思想是先把全部元素按层次遍历放到一棵彻底二叉树中,这棵二叉树须要知足:子节点值都大于父节点值(小顶堆),或子节点值都小于父节点值(大顶堆),步骤以下:

      1. 而后能够知道这棵树中根节点值最小(小顶堆)
      2. 编号最大的元素与根节点元素交换位置,交换位置后取出原根节点元素
      3. 重复12步骤

    仍然以被打乱的7个数字为例:

    排出正确大顶堆:

    而后让根节点位置与最大编号结点位置对调,并断开原根节点与堆的联系,以下:

    从新对剩余的树按大顶堆排序:

    重复上面的步骤,获得:

    按层次遍历,便可获得排序结果。

    从上面也能够看出,按正序排列,须要先构建大顶堆;按逆序排列,须要小顶堆。一位堆排序构建初始堆须要的比较次数较多,因此堆排序不适合元素较少的排序。

交换排序

    交换排序的基本思想是两两进行比较,再根据比较结果决定是否交换位置,主要的交换排序有冒泡法和快速排序法。

    冒泡排序

    恰如其名,冒泡的意思就是假设有两个气泡,重量和待排序中的元素值相同,每次冒泡都让最轻的一个元素向上(前)移动。

    仍然以被打乱的7个数字为例:

    快速排序

    快速排序的基础是分治法,即将问题分解为若干个小可是结构与原问题结构相似的子问题,递归解决这些子问题,再将子问题的解组合为原问题的解。

    仍然以被打乱的7个数字为例,为了更清楚显示,咱们采用逆序排序:

    注意,在选定基准之后,须要左数第几个和右数第几个交替比较:按此例来讲,是基准先与右数第一个比较,再与左数第一个比较,再与右数第二个比较……

    再在前四个元素和后两个元素中选择基准,再按上述步骤排序:

    由于例子比较简单,因此两次就完成排序。快速排序的时间主要是花费在划分操做上,对长度为k的区间进行划分,共须要k-1次关键字比较。它是基于关键字比较的内部算法中最快的一种。

归并排序

    归并排序就是使用合并操做完成排序的算法,若是利用二路合并操做,则称为二路合并排序,它的过程是:

      1. 首先把待排序区间中的每一个元素都看做一个有序表经过两两合并,生n/2(向下取整)个长度为2(最后一个表的长度可能小于2)的有序表,这也称为一趟合并
      2. 而后再将过n/2(向下取整)个有序表进行两两合并,生成比n/4(向下取整)个长度为4的有序表;
      3. 如此循环直到获得一个长度为n的有序表,一般须要log2n趟,若是该值为奇数,则为log2n+1(向下取整)。

    仍然以被打乱的7个数字为例:

归并排序是稳定的排序,可使用顺序存储结构也可使用链表,归并排序须要一个辅助量来暂存两个有序子文件的归并结果。

基数排序

    这个排序方法的基本思路上面几种排序稍有区别,根据小学教的,一个3位数字的大小怎么决定?有百位看百位,没百位的看十位,没十位的比个位。这种方法就是基于此的。

这种排序方法,上面用的“打乱的7个数字”就不合适了,从新选择乱序数集合为:{315,707,101,123,489,918,613},由于是正序排列,因此从个位开始比较。

    个位排序有什么用,这不仍是一点关联也没有吗?开始我也有这个疑问,想着为何不是从百位开始排,那样更一目了然。如今想一想即便按百位开始排,也是把几个百位为某个值的放到一块儿,仍然不能够一蹴而就,更况且,几个无序数列,不知道一共有多少位。一样,按个位开始排序的方法,就至关于先把个位相同的分为一组,若是再按十位排序,须要遵循已经排好的个位序。

 

    继续按百位排序:

       

 

    为了减小元素移动次数,队列能够采用链式存储分配,每一个队列有两个指针,分别指向队头和队尾。

    这个方法思想虽然容易理解,可是由于是从个位开始排,与平常按高位开始排相逆,多少须要思惟的转换,你们能够比对从高位开始排序反过来想从个位排。

对比

各类排序方法之间复杂度与稳定性以下表:

    上述所讲排序不仅是方法,更是思想,例如归并排序:在如今你所处的圈内的值是最高的,若是和其余圈子合并以后呢?呵呵说多了,理解这些排序算法,我以为最重要的几点是:排序的目的、排序对象、每种排序特有的思想,若是能把算法结合到生活当中,忘是忘不掉的。

转自:http://blog.csdn.net/lidatgb/article/details/8044708

相关文章
相关标签/搜索