第八次日志
排序:将一组杂乱无章的数据按一定的规律顺次排
列起来。
内部排序:整个排序过程完全在内存中进行,称为内部排序。
外部排序:由于待排序记录数据量太大,内存无法容纳全部数据,排序需要借助外部存储设备才能完成,称为外部排序。
•假设Ki是Ri 的主关键字,Kj是Rj 的主关键字,
•稳定排序:若Ki=Kj
(1≤i≤n,1≤j≤n,i≠j),在排序
前的序列中Ri领先于Rj(即i<j),经过排序后得到的
序列中Ri仍领先于Rj,则称所用的排序方法是稳定
的 ;
•不稳定排序:反之,当相同关键字的领先关系在排
序过程中发生变化者,则称所用的排序方法是不稳
定的。
在排序过程中,一般进行两种基本操作:
(1)比较两个关键字的大小;
(2)将记录从一个位置移动到另一个位置。
对于第二种操作,需要采用适当的存储方式:
向量结构
链表结构
记录向量与地址向量结合的表示方法
我们重点来讨论在向量存储结构上各种排序方法的
实现。
直接插入排序
基本操作:将第 i 个记录插入到前面 i-1 个已排好序
的记录中
具体过程为:将第 i 个记录的关键字 Ki顺次与其前
面记录的关键字 Ki-1,Ki-2,…K1 进行比较,将所有
关键字大于 Ki的记录依次向后移动一个位置,直到
遇见一个关键字小于或者等于 Ki的记录 Kj,此时
Kj 后面必为空位置,将第 i 个记录插入空位置即可。
直接插入排序算法:
void InsSort(RecordType r[], int length)
/对数组r做直接插入排序,length为记录个数/
{ for ( i=2 ; i< =length ; i++ )//第一个元素已有序
{ r[0]=r[i]; /将待插入记录存放到r[0]中/
j=i-1;
while (r[0].key< r[j].key ) //寻找插入位置
{ r[j+1]= r[j]; //后移
j=j-1;
}
/将待插入记录插入到已排序的序列中/
r[j+1]=r[0];
}} /* InsSort */
该算法的要点是:
①使用监视哨 r[0] 临时保存待插入的记录。
②从后往前查找应插入的位置。
③查找与移动用同一循环完成。
采用监视哨的情况:
•最好的情况:顺序排列
--总的比较次数: n-1次
--总的移动次数: 2(n-1)次
•最坏的情况:逆序排列
--总的比较次数: (n+2)(n-1)/2次
--总的移动次数: (n+4)(n-1)/2次
交换类排序
基本思想:通过交换逆序元素进行排序的方法。
冒泡排序法:
基本思想:反复扫描待排序记录序列,在扫描的过程中顺次比较相邻的两个元素的大小,若逆序则交换位置。
--将待排序的记录看成坚着排列的“气泡”,键值较重的记录比较重,从而往下沉
•最好的情况:顺序排列
--总的比较次数: n-1次
--时间复杂度: O(n)
•最坏的情况:逆序排列
--总的比较次数:n(n-1)/2次
--时间复杂度:O(n2)
快速排序:
算法思想:
以某一元素 v 作为基准,将待排序列分成前后两
段(前段元素均小于 v,后段元素均大于或等于 v)。
再分别对前段、后段元素作快速排序。(递归)
算法分析:
若序列长度为n,划分一次,元素比较n-1次,则进行一次划分,时间复杂度为O(n).
最坏情况:
划分产生的两个序列分别包含n-1个元素和1个元素的时候。时间复杂性为O(n2)。
最好情况:
每次划分所取的基准都恰好为中值,即每次划分都产生2个大小为n/2的区域。时间复杂性为O(nlog2n)