杂谈: 严蔚敏版《数据结构(C语言版)》 一书 终于看完了。这是 一个完结,也是 一个新的开端。《算法导论》 已到手。
置换选择排序的思想 是 将 归并段 尽量 变的 更大,而不是根据 内存 大小 限制在 固定的 大小。 这样 可以 利用赫夫曼树 来 进行 最优归并树,从而 使 外存 读写次数 最少。
下面给出 具体 代码:欢迎指出代码不足。
// Replace_Selcetion.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <climits> #define M 6//内存一次可容纳的 组数 typedef int LoseTree[M]; typedef struct RcdNode { int key; int rNum;//归并段 的段号 }WorkArea[M+1];//内存工作区域。。。 //假设这些文件 存放在 硬盘中.. static int testArray[] = {10,15,169,3,209,18,20,20,22,40,6,15,25,12,37,48,99,100,INT_MAX}; static int readIndex = 0;//读到的索引位置 static int maxIndex = 18; //调整 函数 void select_miniMax(LoseTree t,WorkArea wa,int i){ int f = (i + M) / 2; while (f > 0){ RcdNode n1 = wa[i]; RcdNode n2 = wa[t[f]]; if (n1.rNum > n2.rNum || (n1.rNum == n2.rNum && n1.key > n2.key) ){ int temp = t[f]; t[f] = i; i = temp; } f = f / 2; } t[0] = i; } void initTree(LoseTree t,WorkArea wa){ for (int i = 0; i < M; i++){//初始化段号为0 wa[i].rNum = t[i] = 0; } for (int i = M -1; i>= 0; i--){ wa[i].key = testArray[readIndex++]; wa[i].rNum = 1; select_miniMax(t,wa,i); } } void getRun(LoseTree t,WorkArea wa,int rc,int * rMax){//获得 归并段 printf("-------------------------第%d段------------------------------\n",rc); while (wa[t[0]].rNum == rc){ int q = t[0]; int miniMax = wa[q].key; printf("%d\t",miniMax); //读入 下一个记录 if (readIndex >= maxIndex){//到达记录的结尾 wa[q].rNum = *rMax + 1; wa[q].key = INT_MAX; } else{ int key = wa[q].key = testArray[readIndex++]; if (key < miniMax){ *rMax = rc + 1; wa[q].rNum = *rMax;; } else{ wa[q].rNum = rc; } } select_miniMax(t,wa,q); } printf("\n"); } void replace_Selection(){ LoseTree t; WorkArea wa; initTree(t,wa);//初始化。。 int rc =1, rmax = 1; while (rc <= rmax){ getRun(t,wa,rc,&rmax); rc = wa[t[0]].rNum; } } int _tmain(int argc, _TCHAR* argv[]) { replace_Selection(); return 0; }
测试用例:static int testArray[] = {10,15,169,3,209,18,20,20,22,40,6,15,25,12,37,48,99,100,INT_MAX}
假设 这些数据存放在硬盘中,内存一次只能 读取 6组 数据。 之前的 分配方式,将 18 个数据 分成 3组。现在 分成 2组。一组 11 个,一组 7个。
这样 我们可以 使用 2路 归并,一趟 归并 就行了,总的 外存 读写 次数 为 18。而 被 分成 3组的 方式 需要 2趟 归并,总的 外存读写次数为 36。
肯定 有人 要 说 用 3路 归并 不就 都是 一趟 归并了,总的 外存读写次数 为 18。可是 这样 会 导致 归并的 时间 增加。
时间: 2024-11-06 07:19:04