内部排序算法小结
内部排序算法主要分为插入类排序、交换类排序和选择类排序,它们在性能上的差异主要体现在时间复杂度、空间复杂度和稳定性。各种排序算法都会进行元素间的比较和移动,时间复杂度主要由整个排序过程中的比较次数和移动次数决定。空间复杂度体现在除了待排序记录本身所占的空间,排序过程中占用了多少辅助空间。
1.插入类排序
直接插入排序
如果待排序记录之间是顺序排列,此时整个排序过程中元素比较的次数为n-1次,移动次数为0次。如果待排序记录之间是逆序排列,第i趟排序比较次数为i,移动的次数为i+1,其中i的范围是2到n。因此,整个排序过程中元素的比较次数为(n+2)(n-1)/2,移动次数为(n+4)(n-1)/2。
直接插入排序算法的时间复杂度为O(n^2),空间复杂度为O(1)。从直接插入排序算法的实现可以发现,位置靠后的记录是不可能插入到相同大小的记录之前的,因此直接插入排序算法是稳定的。
折半插入排序
折半插入排序算法与直接插入排序算法相比,每趟的比较次数为log2^i,因此整体的比较次数为O(nlog2^n)。但是折半算法的移动次数较直接插入算法并未改变。
折半算法的时间复杂度仍然是O(n^2),空间复杂度为O(1)。从算法实现可以看出折半插入排序算法是稳定的。
希尔排序
希尔排序利用了当“待排序记录n较小,序列基本有序”时使用直接插入算法性能较好这一特点而改进。希尔排序算法的时间复杂度为O(n^1.5),空间复杂度为O(1),它是不稳定的排序算法。举反例如下:待排序序列为{2,4,1,(2)},设delta[1]=2,则一趟排序后序列为{1,(2),2,4}。
2.交换类排序
冒泡排序
当待排序记录逆序排列时,每趟冒泡算法进行i次比较和3i次交换(两个元素交换),i的范围是1到n-1。因此总的比较次数为n(n-1)/2,总的移动次数为3n(n-1)/2。冒泡排序算法的时间复杂度为O(n^2),空间复杂度O为(1),是一种稳定的排序算法。
快速排序
快速排序最好的情况是每次将待排序的记录都等分为二,此时时间复杂度为O(nlog2^n)。最坏情况下,待排序记录已经排好序,此时总共的比较次数为n(n-1)/2,此时时间复杂度为O(n^2)。
快速排序的平均复杂度为O(nlog2^n),空间复杂度为O(log2^n),它是一种不稳定的排序算法。举反例如下:待排序序列为{3,2,(2)},则一趟排序后记录为{(2),2,3}。
3.选择类排序
简单选择排序
无论待排序记录的初始排列如何,简单选择排序总的比较次数总为n(n-1)/2,因为它每趟比较的次数为n-i,i的范围从1到n-1。最好的情况下,简单选择排序算法的移动次数为0,最坏情况下移动的3(n-1)。
简单选择排序算法的时间复杂度为O(n^2),空间复杂度为O(1),它是不稳定的排序算法。举反例如下:待排序记录为{6,8,(6),2,7},一趟排序后记录为{2,8,(6),6,7},二趟排序后记录为{2,(6),8,6,7}。
堆排序
堆排序的时间复杂度为O(nlog2^n),空间复杂度为O(1),它是不稳定的排序算法。
4.归并排序
归并排序的时间复杂度为O(nlog2^n),空间复杂度为O(n),它是稳定的排序算法。
5.总结
综上所述,内部排序算法的时间复杂度、空间复杂度和稳定性总结如下表:
1.直接插入排序、折半插入排序、冒泡排序和简单选择排序合称为简单排序,它们的时间复杂度均为O(n^2),空间复杂度为O(1)。稳定性方面只有简单选择排序是不稳定的排序算法。简单排序只适合n较小的情况。
2.当待排序记录基本有序时,直接插入排序是最佳的排序算法。它常与快速排序和归并排序等结合使用,因为这些算法会将整个打排序记录划分为若干个子记录,这些子记录数量较小而且基本有序。
3.排序性能较好的有希尔排序、快速排序、堆排序和归并排序,除了希尔排序的时间复杂度为O(n^1.5),其他排序算法均为O(nlogn)。虽然快速排序最坏情况下时间性能下降为O(n^2),但是就平均性能而言快速排序算法是最好的。堆排序和归并排序的性能比较稳定,当n比较大时,归并排序的性能比堆排序要好,但是它需要的辅助空间却为O(n)。
4.所有的排序算法中,不稳定的算法有简单选择排序、希尔排序、快速排序和堆排序。性能较好的排序算法中只有归并排序是稳定的。排序是按记录的主关键字进行的,此时不用考虑排序方法的稳定性。如果排序是按记录的次关键字进行的, 则应充分考虑排序方法的稳定性。