排序:对一序列对象根据某个关键字进行排序;
排序分类:
(1)交换类:冒泡排序、快速排序;此类的特点是通过不断的比较和交换进行排序;
(2)插入类:简单插入排序、希尔排序;此类的特点是通过插入的手段进行排序;
(3)选择类:简单选择排序、堆排序;此类的特点是看准了再移动;
(4)归并类:归并排序;此类的特点是先分割后合并;
上面介绍的排序算法都是基于排序的,还有一类算法不是基于比较的排序算法,如基数排序;
一、冒泡排序
冒泡排序思想:两两相邻元素之间的比较,如果前者大于后者,则交换;
因此此排序属于交换排序一类,同类的还有现在最常用的排序方法即快速排序;
此种方法是最一般的冒泡排序实现,思想就是两两相邻比较并交换;
二、简单选择排序
简单选择排序特点:每次循环找到最小值,并交换,因此交换次数始终为n-1次;
相对于最简单的排序,对于很多不必要的交换做了改进,每个循环不断比较后记录最小值,只做了一次交换(当然也可能不交换,当最小值已经在正确位置)
三、简单插入排序
思想:给定序列,存在一个分界线,分界线的左边被认为是有序的,分界线的右边还没被排序,每次取没被排序的最左边一个和已排序的做比较,并插入到正确位置;我们默认索引0的子数组有序;每次循环将分界线右边的一个元素插入有序数组中,并将分界线向右移一位;
四、希尔排序
基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插人排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。假设待排序文件有10个记录,其关键字分别是: 49,38,65,97,76,13,27,49,55,04。增量序列的取值依次为: 5,3,1
五、堆排序
大根堆:任意父节点都比子节点大;
小根堆:任意父节点都比子节点小;
不稳定排序算法,是简单选择排序的改进版;
思想:构建一棵完全二叉树,首先构建大根堆,然后每次都把根节点即最大值移除,并用编号最后的节点替代,这时数组长度减一,然后重新构建大根堆,以此类推;
注意:此排序方法不适用于个数少的序列,因为初始构建堆需要时间;
六、归并排序
稳定排序算法;
思想:利用递归进行分割和合并,分割直到长度为1为止,并在合并前保证两序列原本各自有序,合并后也有序;
七、快速排序
冒泡排序的升级版;现在用的最多的排序方法;
思想:选取pivot,将pivot调整到一个合理的位置,使得左边全部小于他,右边全部大于他;
注意:如果序列基本有序或序列个数较少,则可以采用简单插入排序,因为快速排序对于这些情况效率不高;
八、基数排序
基数排序也是非比较的排序算法,对每一位进行排序,从最低位开始排序,复杂度为O(kn),为数组长度,k为数组中的数的最大的位数;
如
n个记录的关键字进行排序,每个关键字看成是一个d元组:
ki=(ki1, ki2,..., kid)
其中
c0 <=kij <=cr-1 ( 1 <=i<=n, 1 <=j<=d )
排序时先按kid 的值,从小到大将记录分到r(称为基数)个盒子中,再依次收集;然后按kid-1的值再这样作。直至按ki1分配和收集序列为止,排序结束。
总结: 每个排序都有每个排序的优点,我们需要在适当的时候用适当的算法;
比如在基本有序、数组规模小时用直接插入排序,在大数组时用快速排序,比如如果要想稳定性,则使用归并排序;
详细的对比见
http://zh.wikipedia.org/wiki/%E6%8E%92%E5%BA%8F
以下是我在网上学习排序的时候见到的一些视频,是用跳舞的形式演示排序的步骤,挺形象的,希望会对大家有所帮助
- 冒泡排序视频:http://v.youku.com/v_show/id_XMzMyOTAyMzQ0.html
- 选择排序视频:http://v.youku.com/v_show/id_XMzMyODk5MDI0.html
- 插入排序视频:http://v.youku.com/v_show/id_XMzMyODk3NjI4.html
- 希尔排序视频:http://v.youku.com/v_show/id_XMzMyODk5MzI4.html
- 归并排序视频:http://v.youku.com/v_show/id_XMzMyODk5Njg4.html
- 快速排序视频:http://v.youku.com/v_show/id_XMzMyODk4NTQ4.html