第16周外部排序【项目-1】置换-选择算法模拟
来源:互联网 发布:纽约 伦敦 知乎 编辑:程序博客网 时间:2024/06/16 03:28
编写程序,模拟置换-选择算法生成初始归并段的过程。
设大文件中的记录共有18个: 15 4 97 64 17 32 108 44 76 9 39 82 56 31 80 73 255 68
内存工作区可以容纳5个记录,输出产生的归并段文件。
在模拟中,输入文件数据和输出的归并段数据均直接置在内存中即可。
代码:
#include <stdio.h>#include <malloc.h>#include <string.h>#include <stdlib.h>#define MaxSize 50 //每个文件最多记录数#define MAXKEY 32767 //最大关键字值∞#define W 5 //内存工作区可容纳的记录个数typedef int LoserTree[W]; //败者树是完全二叉树且不含叶子,可采用顺序存储结构typedef int InfoType; //定义其他数据项的类型typedef int KeyType; //定义关键字类型为整型typedef struct //记录类型{ KeyType key; //关键字项 InfoType otherinfo; //其他数据项,具体类型在主程中定义} RecType;typedef struct{ RecType rec; //存放记录 int rnum; //所属归并段的段号} WorkAreaType;typedef WorkAreaType WorkArea[W]; //内存工作区,容量为Wtypedef struct{ RecType recs[MaxSize]; //存放文件中的数据项 int length; //存放文件中实际记录个数 int currec; //存放当前位置} FileType; //文件类型FileType Fi; //定义输入文件,为全局变量FileType Fo; //定义输出文件,为全局变量void initial() //输入输出文件初始化{ int n=19,i; KeyType a[]= {15,4,97,64,17,32,108,44,76,9,39,82,56,31,80,73,255,68,MAXKEY}; for (i=0; i<n; i++) Fi.recs[i].key=a[i]; Fi.length=n; Fi.currec=-1; Fo.currec=-1; Fo.length=0;}void Select_MiniMax(LoserTree ls, WorkArea wa,int q)//从wa[q]起到败者树的根比较选择最小记录,并由q指示它所在的归并段{ int p,s,t; for (t=(W+q)/2,p=ls[t]; t>0; t=t/2,p=ls[t]) if ((wa[p].rnum<wa[q].rnum) || (wa[p].rnum==wa[q].rnum && wa[p].rec.key<wa[q].rec.key)) { s=q; q=ls[t]; //q指示新的胜者 ls[t]=s; } ls[0]=q;}void Construct_Loser(LoserTree ls,WorkArea wa)//输入W个记录到内存工作区wa,建败者树ls,选最小的记录并由s指示其在wa中的位置{ int i; for(i=0; i<W; i++) wa[i].rnum=wa[i].rec.key=ls[i]=0; //工作区初始化 for(i=W-1; i>=0; i--) { Fi.currec++; //从输入文件读入一个记录 wa[i].rec=Fi.recs[Fi.currec]; wa[i].rnum=1; //其段号为1 Select_MiniMax(ls,wa,i); //调整败者 }}void get_run(LoserTree ls,WorkArea wa,int rc,int &rmax)//求得一个初始归并段{ int q; KeyType minimax; //当前最小关键字 while (wa[ls[0]].rnum==rc) //选得的当前最小记录属当前段时 { q=ls[0]; //q指示当前最小记录在wa中的位置 minimax=wa[q].rec.key; Fo.currec++; //将刚选得的当前最小记录写入输出文件 Fo.length++; Fo.recs[Fo.currec]=wa[q].rec; Fi.currec++; //从输入文件读入下一记录 wa[q].rec=Fi.recs[Fi.currec]; if (Fi.currec>=Fi.length-1) //输入文件结束,虚设记录(属rmax+1段) { wa[q].rnum=rmax+1; wa[q].rec.key=MAXKEY; } else //输入文件非空时 { if(wa[q].rec.key<minimax) { rmax=rc+1; //新读入的记录属下一段 wa[q].rnum=rmax; } else //新读入的记录属当前段 wa[q].rnum=rc; } Select_MiniMax(ls,wa,q); //选择新的当前最小记录 }}void Replace_Selection(LoserTree ls,WorkArea wa)//在败者树ls和内存工作区wa上用置换-选择排序求初始归并段{ int rc,rmax; RecType j; //j作为一个关键字最大记录,作为一个输出段结束标志 j.key=MAXKEY; Construct_Loser(ls,wa); //初建败者树 rc=1; //rc指示当前生成的初始归并段的段号 rmax=1; //rmax指示wa中关键字所属初始归并段的最大段号 while(rc<=rmax) //rc=rmax+1标志输入文件的置换-选择排序已完成 { get_run(ls,wa,rc,rmax); //求得一个初始归并段 Fo.currec++; //将段结束标志写入输出文件 Fo.recs[Fo.currec]=j; Fo.length++; rc=wa[ls[0]].rnum; //设置下一段的段号 }}int main(){ int i=0,rno=1; initial(); LoserTree ls; WorkArea wa; printf("大文件的记录为:\n "); while (Fi.recs[i].key!=MAXKEY) { printf("%d ",Fi.recs[i].key); i++; } printf("\n"); Replace_Selection(ls,wa); //用置换-选择排序求初始归并段 printf("产生的归并段文件的记录如下:\n"); printf(" 归并段%d:",rno); //输出所有的归并段 for (i=0; i<Fo.length; i++) if (Fo.recs[i].key==MAXKEY) { printf("∞"); if (i<Fo.length-1) { rno++; printf("\n 归并段%d:",rno); } } else printf("%d ",Fo.recs[i].key); printf("\n 共产生%d个归并段文件\n",rno); return 0;}
运行结果:
心得与体会:
这代码太长了!!
0 0
- 第16周外部排序【项目-1】置换-选择算法模拟
- 16周——项目一:置换-选择算法模拟
- 选择置换+败者树搞定外部排序
- 选择置换+败者树搞定外部排序
- 第16周外部排序之【项目2】败者树归并模拟
- 第16周项目1-验证算法(5)直接选择排序
- 第16周项目1 验证算法(5)直接选择排序
- 第16周项目1-验证算法(5)直接选择排序
- 第16周SHH数据结构-【项目1-验证算法(5)直接选择排序 】
- 第16周项目1-验证算法(5)直接选择排序
- 第16周 项目1-验证算法(直接选择排序)
- 第16周项目1-验证算法(5)直接选择排序
- 第16周项目1-验证算法(5)直接选择排序
- 第16周项目1 验证算法(5)直接选择排序
- 第16周项目1-验证算法(5)直接选择排序
- 第16周项目1-验证算法(5)直接选择排序
- 第16周项目选择排序之直接选择排序
- C++代码,数据结构-外部排序-置换-选择排序
- 验证算法(6)堆排序
- 数据结构实践——(3)验证算法——二叉排序树相关算法
- 汇编指令---CDQ
- 第16周项目1 验证算法(6)堆排序
- 第13周项目验证算法(1)、(2)
- 第16周外部排序【项目-1】置换-选择算法模拟
- 第十六周上机实践—项目3—归并排序算法的改进
- 2015-12-18 第十六周 项目3 - 归并排序算法的改进
- 支持多层嵌套RadioButton的RadioGroup
- 第十周项目2二叉树遍历的递归算法
- 第16周项目1-插入排序之直接插入排序(1)
- 学期总结
- 验证算法(7)归并排序
- 第9周 项目4—广义表算法库及应用 .