排序序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
一、插入排序
1、直接插入排序
基本思想:
将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:
设立哨兵,作为临时存储和判断数组边界之用。
思路:
第一趟:插入49,就一个值(有序序列)
第二趟:插入38,38与49比较,38小于49,放在其前面
第三趟:插入65,65与49比较,65大于49,放在其后面(不用于38进行比较,只有比49小的数才有必要与38进行比较)
……
……
最后,排成有序序列
小结:
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
2、希尔排序
基本思想:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
要点:
本质:分组排序
假设:增量为X,总数:n。X1一般取:n/2;X2取:X1/2;依次类推。
注意:如果结果为偶数则加1保证增量为奇数。
思路:
例:n=10
第一趟:X1=n/2=5
第二趟:X2=5/2=3
第三趟:X2=3/2=1
最后一趟:按直接插入排序
二、选择排序
1、简单选择排序
基本思想:
在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
要点:
与冒泡排序的区别:需要引入变量
思路:
第一趟,从n个记录中找出关键码最小的记录与第一个记录交换;
第二趟,从第二个记录开始的n-1个记录中再选出关键码最小的记录与第二个记录交换;
以此类推.....
第i趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与第i 个记录交换,
直到整个序列按关键码有序。
2、堆排序
基本思想:
堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足
时称之为堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最小项(小顶堆)。
若以一维数组存储一个堆,则堆对应一棵完全二叉树,且所有非叶结点的值均不大于(或不小于)其子女的值,根结点(堆顶元素)的值是最小(或最大)的。
要点:
小根堆:根结点是最小的;
大根堆:跟结点是最大的;
思路:
步骤一:如何建立初始堆;从第i=[n/2]节点开始到树的根结点为止
步骤二:当堆的根节点与堆的最后一个结点交换后,如何对少了一个结点后的结点序列做调整,重新建立堆。
初堆:
顺序调整:
三、交换排序
1、冒泡排序
基本思想
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
思路
2、快速排序
基本思想
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
思路
(a)一趟排序的过程:
(b)排序的全过程
四、其他
1、归并排序
基本思想
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
示例:
注意:
[3,5][2,9]:需要比较3次。
第一次:3,2
第二次:3,9
第三次:5,2
2、基数排序
基本思想
从低位到高位依次对待排序的关键码进行分配和收集,经过d趟分配和收集,就可以得到一个有序序列。就是把关键字按原子分开,对每个原子实例:
进行排序
例:{288,371,260,531,287,235,56,299,18,23}基数排序
第一趟收集个位,排序结果:{260,371,531,23,235,56,287,288,18,299}
第二趟收集十位,排序结果:{18,23,531,235,56,260,371,287,288,299}
第三趟收集百位,排序结果:{18,23,56,235,260,287,288,299,371,531}
五、稳定性
1、定义
排序算法的稳定性:若待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;若经排序后,记录的相对次序发生了改变,则称该算法是不稳定的。
例如:Ai= Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。
2、好处
稳定性的好处:排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。另外,如果排序算法稳定,可以避免多余的比较;
3、算法
稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序
不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序
六、各种排序的稳定性,时间复杂度和空间复杂度总结:
我们比较时间复杂度函数的情况: