数据结构:排序(2)
四、归并排序
1.自底向上
- 基本思想:第1趟归并排序时,将待排序的文件R[1..n]看作是n个长度为1的有序子文件,将这些子文件两两归并,若n为偶数,则得到 个长度为2的有序子文件;若n为奇数,则最后一个子文件轮空(不参与归并)。故本趟归并完成后,前lgn个有序子文件长度为2,但最后一个子文件长度仍为1;第2趟归并则是将第1趟归并所得到的lgn个有序的子文件两两归并,如此反复,直到最后得到一个长度为n的有序文件为止。
- 算法描述:动画演示过程
2.自顶向下
- 基本思想:①分解:将当前区间一分为二,即求分裂点 ②求解:递归地对两个子区间R[low..mid]和R[mid+1..high]进行归并排序;③组合:将已排序的两个子区间R[low..mid]和R[mid+1..high]归并为一个有序的区间R[low..high]。 递归的终结条件:子区间长度为1(一个记录自然有序)。
- 算法描述:
五、分配排序
分配排序的基本思想:排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n)。 1.箱排序
- 基本思想:设置若干个箱子,依次扫描待排序的记录R[0],R[1],…,R[n-1],把关键字等于k的记录全都装入到第k个箱子里(分配),然后按序号依次将各非空的箱子首尾连接起来(收集)。
2.基数排序
- 基本思想:从低位到高位依次对Kj(j=d-1,d-2,…,0)进行箱排序。在d趟箱排序中,所需的箱子数就是基数rd,这就是"基数排序"名称的由来。借助多关键字排序的思想对单逻辑关键字进行排序的方法。
各种内部排序方法的比较和选择
1 ///Name:Tree 2 ///Author:JA 3 ///Date:2015-3-14 4 5 6 7 void MergePass(SeqList R,int length) 8 { //对R[1..n]做一趟归并排序 9 int i; 10 for (i = 1; i + 2 * length - 1 <= n; i = i + 2 * length) 11 Merge(R,i,i + length - 1,i + 2 * length - 1); 12 //归并长度为length的两个相邻子文件 13 if (i + length - 1 < n) //尚有两个子文件,其中后一个长度小于length 14 Merge(R, i, i + length - 1, n); //归并最后两个子文件 15 //注意:若i≤n且i+length-1≥n时,则剩余一个子文件轮空,无须归并 16 } //MergePass 17 18 void BucketSon(R) 19 { //对R[0..n-1]做桶排序,其中0≤R[i].key<1(0≤i<n) 20 for (i = 0,i<n; i++) //分配过程. 21 //将R[i]插入到桶B[「n(R[i].key)」]中; //可插入表头上 22 for (i = 0; i<n; i++) //排序过程 23 //当B[i]非空时用插人排序将B[i]中的记录排序; 24 for (i = 0, i < n; i++) //收集过程 25 //若B[i]非空,则将B[i]中的记录依次输出到R中; 26 }
3/14/2015 2:55:05 PM