排序算法讲解

排序方法:排序主要包含内部排序和外部排序。
内部排序(简称内排序),是指所有待排序内容都存储在内存的排序。
外部排序(简称外排序),是指有部分待排序内容没有存储在内存,而是被存储在硬盘的排序。
内排序适用于规模在千万量级内的数据,外排序适用于大规模的数据。由于外排序的操作需要和硬盘进行反复交互,所以效率要比内排序低。
内排序主要有三种方法:插入排序、选择排序和交换排序。
外排序主要是用归并排序。基数排序和桶排序,其本质是将排序的数据填入“键值已排序的Hash表”。在待排序的文件中,若存在多个关键字相同的记录,经过排序后,这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生改变,则称这种排序是不稳定的。

1,插入排序
插入排序的基本思想是每步将一个待排序的记录按其排序码值的大小,插到前面已经排好的文件中的适当位置,直到全部插入完为止。

算法步骤:
1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成未排序序列。
2)从头到尾一次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置(如果带插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等的元素后面。)

1.1 希尔排序
希尔排序也叫递减增量排序算法,是插入排序的一种更高效的改进版本。但是希尔排序是非稳定排序算法。
希尔排序是基于插入排序的一下两点性质而提出改进方法的:插入排序在对几乎已经排序好的额数据操作时,效率高,既可以达到线性排序的效率;但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录基本有序时,再对全体记录进行依次直接插入排序。


排序算法讲解_第1张图片

算法步骤:
1)选择一个增量序列t1,t2,...tk,其中ti>tj,tk=1;
2) 按增量序列个数k,对序列进行k趟排序;
3)每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各子序表进行直接插入排序。仅增量因子为1时,整个序列作为一个表来处理,表长度即为整个序列的长度。

2、选择排序
选择排序的基本思想是每步从待排序的记录中选出排序码最小的记录,顺序存放在已排序的记录序列的后面,直到全部不排序完成。选择排序中主要使用直接选择排序和堆排序。


排序算法讲解_第2张图片

2.1堆排序堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总小于(或大于)它的父节点。
堆排序的平均时间复杂度为O(nlogn)。

排序算法讲解_第3张图片

算法步骤:
1)创建一个堆H[0...n-1]
2)把堆首(最大值)和堆尾互换
3)把堆得尺寸缩小1,并调用shift_down(0),目的是把新的数组顶端数据调整到相应位置;
4)重复步骤2,直到堆得尺寸为1

3、快速排序
快速排序是一种不稳定的排序。快速排序的精髓在于随机化。快速排序运用了分治法,其基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题,然后递归地解这些子问题,最后将这些子问题的解组合为原问题的解。


排序算法讲解_第4张图片

算法步骤:
1)在待排序的n个记录中任取一个记录,以该记录的排序码为准,将所有的记录分成两组,第一组中各记录的排序码都小于或等于该排序码,第二组中各记录的排序码都大于该排序码,并把该记录排在两组中间。
2)采用同样的方法,在最左边的组合右边的组进行排序,直到所有的记录都排到相应的位置为止。

4、归并排序
归并排序是一种外排序方法,也是一种稳定的排序,其精髓在于分治法。归并排序将两个或两个以上的有序子表合成一个新的有序表。初始时,把含有n个结点的待排序序列看作由n个长度都为1的有序子表组成,将它们一次两两归并并得到长度为2的若干个有序子表,再对它们两两进行合并,直到得到长度为n的有序表。归并排序可用顺序存储结构,也易于在链表上实现,对长度为n的文件,需进行logn趟二路归并,每趟归并的时间为O(n),故其时间复杂度在最好和最坏情况下均是O(nlogn)。归并排序需要一个辅助向量来暂存两个有序子文件归并的结果,故其辅助空间复杂度为O(n)。


排序算法讲解_第5张图片

算法步骤:
1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
2)设定两个指针,最初位置分别为两个已经排序序列的起始位置;
3)比较两个指针所指向的元素,选择相对小的元素放入合并空间,并移动指针到下一位置;
4)重复步骤3直到某一指针达到序列尾;
5)将序列剩下的所有元素直接复制到合并序列列尾。

5、基数排序
基数排序的基本思想是:从低位到高位依次对待排序的关键字(r个)进行分配和收集,经过d趟分配和收集后,就可以得到一个有序序列。

6、冒泡排序(Bubble Sort)
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
算法步骤:
1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3)针对所有的元素重复以上的步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

总结

各种排序的稳定性,时间复杂度、空间复杂度、稳定性总结如下图:


排序算法讲解_第6张图片

关于时间复杂度:
(1)平方阶(O(n2))排序各类简单排序:直接插入、直接选择和冒泡排序;
(2)线性对数阶(O(nlog2n))排序  快速排序、堆排序和归并排序;(3)O(n1+§))排序,§是介于0和1之间的常数。
希尔排序(4)线性阶(O(n))排序基数排序,此外还有桶、箱排序。
在不同的环境下,挑选排序的大致原则如下。
1)需要存储在硬盘上的海量数据排序因为数据量大,只能存储在硬盘上,所以应该用归并排序。
2)在内存上的排序规则如下。
(1)若n较小(如n<=50),排序方法可随意选择;
(2)若n较大,则应采用时间复杂度为O(nlogn)的排序方法:快速排序、堆排序。这两种排序的效果最明显。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字随机分布时,快速排序的平均时间最短。
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。
关于稳定性:
稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序
不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序

参考链接:http://www.cricode.com/3212.html
原文链接:http://blog.csdn.net/u010963246/article/details/52985330

你可能感兴趣的:(排序算法讲解)