第十章 排序目录
第十章 排序
1、排序的基本概念
排序算法的稳定性:
在排序后,相同键值的元素(或称之为记录)的相对位置不发生改变,则说明这种排序算法是稳定的,否则就是不稳定的。
1、交换排序
1)冒泡排序
主要操作是:交换
主要思想是:在待排序列中选两个记录,将他们的关键码相比较,如果反序(即排列顺序与排序后的次序正好相反),则交换他们的存储位置。
对传统冒泡排序进行改进
改进1:增设一个exchange变量
exchange变量记录是否发生交换,如果未发生交换即终止循环继续。
改进2:exchange变量记录发生交换的位置
处理1: exchange记载这一趟排序中记录的最后一次交换的位置,且从此位置之后的所有记录都已经有序。
处理2 :设bound位置是记录无序区的最后一个记录,则每趟冒泡排序的范围是r[1] ~ r[bound] 。
在一趟排序后,从exchange位置之后的记录一定是有序的,所以bound=exchange。
改进3:增加2个记录位,双向冒泡排序
2个记录位,双向记录发生交换的最后位置,在排序的过程中交替改变扫描方向。
2)快速排序
<1>基本思想
先选定一个轴值(即比较的基准),通过一趟排序将待排序记录分割成独立的两部分,前一部分记录的关键码均小于或等于轴值,后一部分的关键码均大于或等于轴值,然后对这两部分重复上述办法,直到整个序列有序。
<2>选择轴值
<3>实现一次划分
<4>分割得到两个待排序子序列
解决办法:对分割得到的两个子序列递归地执行快速排序。
<5>性能分析
快速排序是一种不稳定的排序算法。比如:2、1、1
2、插入排序
基本思想:
将待排序表看做是左、右两部分,其中左边为有序区,右边为无序区,整个排序过程就是将右边无序区中的记录依次按关键字大小逐个插入到左边有序区中,已构成新的有序区,直到全部记录都排好序。
1)直接插入排序
基本思想:
性能分析
是一种稳定的排序算法。
2)折半插入排序
在插入排序的过程中可以利用折半查找的方法来确定记录的插入位置,此方法叫做折半插入排序。
采用折半插入排序算法,可以减少关键字的比较次数,数量级为
O(nlog2 n) ,但并未改变移动元素的时间耗费,所以此方法总的时间复杂度为O(nn)*.
3)希尔排序
基本思想:
是对直接插入排序进行改进。
(1)先将待排序列划分为若干小序列,在这些小序列中进行插入排序。
(2)再逐步扩大小序列的长度,减少小序列的个数,使得待排序列逐渐处于更有序的状态。
(3)最后对全体序列进行一次直接插入排序。
希尔排序过程:
<1>分割待排序记录
<2>子序列内进行直接插入排序
<3>性能分析
3、选择排序
主要操作: 选择
==主要思想:==第 i 趟在n-i+1(i=1,2,…,n-1)个记录中选取关键码最小的记录作为有序序列的第 i 个记录。
==适用场景:==适合从大量记录中选择一部分排序记录的问题,因为选择排序方法每一趟总是从无序区中选出全局最小(或最大)的关键字记录。
1)简单选择排序
性能分析
是一个稳定的排序算法。时间复杂度是O(nn)*
2)堆排序
是简单排序的改进。
<1> 基本思想
先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者,然后将它从堆中移走,并将剩余的记录再调整成堆,这样又找出了次小记录,以此类推,直到堆中只有一个记录。
<2> 堆调整和建堆
<3> 性能分析
4、归并排序
主要思想:
将若干有序序列逐步归并,最终得到一个有序序列。
归并: 将两个或两个以上的有序序列归并成一个有序序列的过程。
**过程:**将一个具有n个待排序记录的序列看成是n个长度为1的有序序列,然后进行两两归并,得到 n/2 个长度为2的有序序列,在进行两两归并,得到 n/4 个长度为4的有序序列,直到得到一个长度为n的有序序列。