排序冒泡选择堆归并.docx
- 文档编号:9816930
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:15
- 大小:265.85KB
排序冒泡选择堆归并.docx
《排序冒泡选择堆归并.docx》由会员分享,可在线阅读,更多相关《排序冒泡选择堆归并.docx(15页珍藏版)》请在冰豆网上搜索。
排序冒泡选择堆归并
课程名称:
数据结构开课实验室:
计算中心204室2011年12月日
年级、专业、班
学号
姓名
成绩
实验项目名称
实现排序、冒泡、选择、堆、归并的算法
指导教师
教师
评语
教师签名:
年月日
1、实验内容和目的
目的:
实现排序、冒泡、选择、堆、归并的算法。
内容:
撑握排序、冒泡、选择、堆、归并的算法和使用,熟悉并学会运用排序、冒泡、选择、堆、归并的算法内容和相互间的转变等。
二、上机实验环境
计算中心204;操作系统:
MicrosoftVisualC++;软件平台:
MicrosoftVisualC++
三、上机操作方法、步骤
打开计算机进入WindowsXP→在桌面建立自己的工作目录→进入MicrosoftVisualC++6.0→文件/新建/文件/C++SourceFile/位置/命名→输入源程序→编译/组建→运行。
#include
#include
#defineMax100//假设文件长度
typedefstruct{//定义记录类型
intkey;
}RecType;
typedefRecTypeSeqList[Max+1];//SeqList为顺序表,表中第0个元素作为哨兵
intn;//顺序表实际的长度
intmenu();
//-----------------------------------------------------------------------------------------
voidInsertSort(SeqListR)//直接插入排序法
{//对顺序表R中的记录R[1‥n]按递增序进行插入排序
inti,j;
for(i=2;i<=n;i++)//依次插入R[2],……,R[n]
if(R[i].key R[0]=R[i];j=i-1;//R[0]是R[i]的副本 do {//从右向左在有序区R[1‥i-1]中查找R[i]的位置 R[j+1]=R[j];//将关键字大于R[i].key的记录后移 j--; } while(R[0].key R[j+1]=R[0];//R[i]插入到正确的位置上 }//endif } //------------------------------------------------------------------------------------------ intPartition(SeqListR,inti,intj)//一次划分函数 {//对R[i‥j]做一次划分,并返回基准记录的位置 RecTypepivot=R[i];//用第一个记录作为基准 while(i while(i j--;//从右向左扫描,查找第一个关键字小于pivot.key的记录R[j] if(i R[i++]=R[j];//交换R[i]和R[j],交换后i指针加1 while(i i++;//从左向右扫描,查找第一个关键字小于pivot.key的记录R[i] if(i R[j--]=R[i];//交换R[i]和R[j],交换后j指针减1 } R[i]=pivot;//此时,i=j,基准记录已被最后定位 returni;//返回基准记录的位置 } //-------------------------------------------------------------------------------------------- voidQuickSort(SeqListR,intlow,inthigh)//快速排序 {//R[low..high]快速排序 intpivotpos;//划分后基准记录的位置 if(low pivotpos=Partition(R,low,high);//对R[low..high]做一次划分,得到基准记录的位置 QuickSort(R,low,pivotpos-1);//对左区间递归排序 QuickSort(R,pivotpos+1,high);//对右区间递归排序 } } //-------------------------------------------------------------------------------------------- voidSelectSort(SeqListR)//直接选择排序 { inti,j,k; for(i=1;i k=i; for(j=i+1;j<=n;j++)//在当前无序区R[i‥n]中选key最小的记录R[k] if(R[j].key k=j;//k记下目前找到的最小关键字所在的位置 if(k! =i){////交换R[i]和R[k] R[0]=R[i]; R[i]=R[k]; R[k]=R[0]; } } } //------------冒泡排序------------------------------------------------------------------------ typedefenum{FALSE,TRUE}Boolean;//FALSE为0,TRUE为1 voidBubbleSort(SeqListR){//自下向上扫描对R做冒泡排序 inti,j;Booleanexchange;//交换标志 for(i=1;i exchange=FALSE;//本趟排序开始前,交换标志应为假 for(j=n-1;j>=i;j--)//对当前无序区R[i‥n]自下向上扫描 if(R[j+1].key R[0]=R[j+1];//R[0]不是哨兵,仅做暂存单元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE;//发生了交换,故将交换标志置为真 } if(! exchange)//本趟排序未发生交换,提前终止算法 return; }//endfor(为循环) } //---------------------------------------------------------------------------------------------------- voidHeapify(SeqListR,intlow,inthigh)//大根堆调整函数 {//将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质 intlarge;//large指向调整结点的左、右孩子结点中关键字较大者 RecTypetemp=R[low];//暂存调整结点 for(large=2*low;large<=high;large*=2){//R[low]是当前调整结点 //若large>high,则表示R[low]是叶子,调整结束;否则先令large指向R[low]的左孩子 if(large large++;//若R[low]的右孩子存在且关键字大于左兄弟,则令large指向它 //现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者 if(temp.key>=R[large].key)//temp始终对应R[low] break;//当前调整结点不小于其孩子结点的关键字,结束调整 R[low]=R[large];//相当于交换了R[low]和R[large] low=large;//令low指向新的调整结点,相当于temp已筛下到large的位置 } R[low]=temp;//将被调整结点放入最终位置上 } //构造大根堆 voidBuildHeap(SeqListR) {//将初始文件R[1..n]构造为堆 inti; for(i=n/2;i>0;i--) Heapify(R,i,n);//将R[i..n]调整为大根堆 } //堆排序 voidHeapSort(SeqListR) {//对R[1..n]进行堆排序,不妨用R[0]做暂存单元 inti; BuildHeap(R);//将R[1..n]构造为初始大根堆 for(i=n;i>1;i--){//对当前无序区R[1..i]进行堆排序,共做n-1趟。 R[0]=R[1];R[1]=R[i];R[i]=R[0];//将堆顶和堆中最后一个记录交换 Heapify(R,1,i-1);//将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质。 } } //-------------------------------------------------------------------------------------- //将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high] voidMerge(SeqListR,intlow,intm,inthigh) { inti=low,j=m+1,p=0;//置初始值 RecType*R1;//R1为局部量 R1=(RecType*)malloc((high-low+1)*sizeof(RecType));//申请空间 while(i<=m&&j<=high)//两个子序列非空时取其小者输出到R1[p]上 R1[p++]=(R[i].key<=R[j].key)? R[i++]: R[j++]; while(i<=m)//若第一个子序列非空,则复制剩余记录到R1 R1[p++]=R[i++]; while(j<=high)//若第二个子序列非空,则复制剩余记录到R1中 R1[p++]=R[j++]; for(p=0,i=low;i<=high;p++,i++) R[i]=R1[p];//归并完成后将结果复制回R[low..high] } //----------------------------------------------------------------------------------- voidMergePass(SeqListR,intlength)//对R[1..n]做一趟归并排序 { inti; for(i=1;i+2*length-1<=n;i=i+2*length) Merge(R,i,i+length-1,i+2*length-1);//归并长度为length的两个相邻的子序列 if(i+length-1 Merge(R,i,i+length-1,n);//归并最后两个子序列 //注意: 若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并 } //----------------------------------------------------------------------------------- voidMergeSort(SeqListR)//自底向上对R[1..n]做二路归并排序 { intlength; for(length=1;length MergePass(R,length);//有序长度≥n时终止 } //----------------------------------------------------------------------------------- voidinput_int(SeqListR)//输入顺序表 { inti; printf("请输入个数(int): "); scanf("%d",&n); printf("请输入一组数据: ",n); for(i=1;i<=n;i++) scanf("%d",&R[i].key); } //---------------------------------------------------------------------------------- voidoutput_int(SeqListR)//输出顺序表 { inti; for(i=1;i<=n;i++) printf("%4d",R[i].key); printf("\n\n"); } //--------------------------------------------------------------------------------- voidmain()//主函数 { //inti; SeqListR; input_int(R); while (1){ system("cls"); inti=menu(); switch(i) { case1: InsertSort(R);break;//值为1,直接插入排序 case2: BubbleSort(R);break;//值为2,冒泡法排序 case3: QuickSort(R,1,n);break;//值为3,快速排序 case4: SelectSort(R);break;//值为4,直接选择排序 case5: HeapSort(R);break;//值为5,堆排序 case6: MergeSort(R);break;//值为6,归并排序 case7: exit(0);break;//值为7,结束程序 } printf("所选排序的结果: "); printf("\n"); output_int(R); if(i! =7) { puts("\n\n操作成功! "); system("pause"); } } } //---------------------------------------------------- intmenu() { intn; printf("\t----------选择操作----------\n"); printf("\t1: 直接插入排序\n"); printf("\t2: 冒泡法排序\n"); printf("\t3: 快速排序\n"); printf("\t4: 直接选择排序\n"); printf("\t5: 堆排序\n"); printf("\t6: 归并排序\n"); printf("\t7: 退出\n"); printf("\t-----------------------------\n"); fflush(stdin); scanf("%d",&n);//输入整数1-7,选择排序方式 returnn; } 四、源程序与运行结果: <1>图为输入要排序的一组数据 <2>数据输完后,回车出现选择所要的排序法 <3>图为选择“直接插入排序法” <4>图为选择“冒泡法排序法” <5>图为选择“快速排序法” <6>图为选择“直接选择排序法” <7>图为选择“堆排序法” <8>图为选择“归并排序法” <9>图为程序成功退出 五、上机实践收获和体会: 这几次的上机实践课,让我知道计算机专业需要相当多的实践,而在实践中不但掌握计算机技术(包括程序设计),还要掌握许多其他专业并不“深究”的东西,例如,算法,体系结构,信息管理等等。 对于我这个初学者的知识基础较薄弱,对一些应用操作理解起来较为困难,要能从整体概念上较好地理解和把握应用软件,不是仅仅靠几本培训的书籍还买了几本有关专业的书籍,细致地看几遍,然后上机练习几次就可以成功。 本专的同学也都在说,学习编程的秘诀是: 编程,编程,再编程。 我今后会更努力的去学习这门课。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序 冒泡 选择 归并