《数据结构》内部排序12种算法上机实验报告word文档良心出品.docx
- 文档编号:6217092
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:19
- 大小:208.03KB
《数据结构》内部排序12种算法上机实验报告word文档良心出品.docx
《《数据结构》内部排序12种算法上机实验报告word文档良心出品.docx》由会员分享,可在线阅读,更多相关《《数据结构》内部排序12种算法上机实验报告word文档良心出品.docx(19页珍藏版)》请在冰豆网上搜索。
《数据结构》内部排序12种算法上机实验报告word文档良心出品
成都信息工程学院计算机系
课
程
实
验
报
告
实验课程:
数据结构
实验项目:
实现算法的全排序
指导教师:
学生姓名:
学生学号:
班级:
计算机工程1班
实验地点:
6305
实验时间:
2012年12月2日—12月19日
实验成绩:
评阅老师:
(说明:
实验报告必须包含下面的每项内容,根据实验情况认真填写,封面必须打印或复印(A4纸),书写上机实验报告内容的纸张也用A4纸,最后从侧面装订)
一【上机实验目的】
目的:
从键盘输入一组数,通过内部排序的12种算法对这组数字进行排序。
熟练掌握刚刚学过的内部排序的算法,并对这12种排序算法的时间复杂度进行比较,根据不同的情况,选择合适的算法
二【实验环境】
PC机每人1台
三【上机实验内容】
实现内部排序的12种排序算法的全排序。
四【上机调试程序流程图】(注:
可打印)
(用传统流程图的形式表示)
五【上机调试中出现的错误信息、错误原因及解决办法】
(记录下你调试程序中出现的错误信息的英文提示,分析出错原因及可能的解决办法)
六【上机调试后的源程序及还存在的问题】(注:
源程序可打印)
(同时记录下你对你编写此程序的其它具体想法,)
主要的程序:
/********************************直接插入排序***************************/
voidInsertSort(SqList&L)
{//直接插入排序
inti,j;
for(i=2;i<=L.length;++i)
{
if(L.r[i].key<=L.r[i-1].key)
{
L.r[0]=L.r[i];
L.r[i]=L.r[i-1];
for(j=i-2;(L.r[0].key L.r[j+1]=L.r[j]; L.r[j+1]=L.r[0]; } } } /*********************************折半插入排序************************/ voidBinsertSort(SqList&L) {//折半插入排序 inti,j,low,high,m; for(i=2;i<=L.length;i++) { L.r[0]=L.r[i]; low=1; high=i-1; while(low<=high) { m=(low+high)/2; if(L.r[0].key high=m-1; else low=m+1; } for(j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j]; L.r[high+1]=L.r[0]; } } /**********************************2-路插入排序***********************/ voidP2_InsertSort(SqList&L) {//2—路插入排序 inti,j,first,final; RedType*d; d=(RedType*)malloc(L.length*sizeof(RedType));//生成L.length个记录的临时空间 d[0]=L.r[1]; first=final=0;//first、final分别指示d中排好序的记录的第1个和最后1个记录的位置 for(i=2;i<=L.length;++i) {//依次将L的第2个~最后1个记录插入d中 if(L.r[i].key {//待插记录小于d中最小值,插到d[first]之前(不需移动d数组的元素) first=(first-1+L.length)%L.length;//设d为循环向量 d[first]=L.r[i]; } elseif(L.r[i].key>d[final].key) {//待插记录大于d中最大值,插到d[final]之后(不需移动d数组的元素) final=final+1; d[final]=L.r[i]; } else {//待插记录大于d中最小值,小于d中最大值,插到d的中间(需要移动d数组的元素) j=final++;//移动d的尾部元素以便按序插入记录 while(L.r[i].key { d[(j+1)%L.length]=d[j]; j=(j-1+L.length)%L.length; } d[j+1]=L.r[i]; } } for(i=1;i<=L.length;i++)//把d赋给L.r L.r[i]=d[(i+first-1)%L.length];//线性关系 } /***************************************希尔排序***************************/ voidShellInsert(SqList&L,intdk) { //printf("OK"); inti,j; for(i=dk+1;i<=L.length;i++) if(L.r[i].key { L.r[0]=L.r[i]; for(j=i-dk;j>0&&(L.r[0].key L.r[j+dk]=L.r[j]; L.r[j+dk]=L.r[0]; } } voidShellSort(SqList&L,intdlta[],intt) { //printf("OK"); intk; for(k=0;k ShellInsert(L,dlta[k]); //display(L); } /***********************************表插入排序***********************/ voidTableInsert(SLinkListType&SL,RedTypeD[]){ //由数组D建立的n个元素的表插入排序的静态链表SL inti,p,q; SL.r[0].rc.key=INT_MAX;//表头结点记录的关键字取得最大整数(非降序表的表尾) SL.r[0].next=0;//next域为0表示表尾(现为空表,初始化) for(i=0;i SL.r[i+1].rc=D[i];//将数组D的值赋给静态链表SL q=0; p=SL.r[0].next; while(SL.r[p].rc.key<=SL.r[i+1].rc.key){//静态链表后移 q=p; p=SL.r[p].next; } SL.r[i+1].next=p; SL.r[q].next=i+1;//将当前记录插入到静态链表 } SL.length=MAXSIZE; } voidArrange(SLinkListType&SL) { //根据静态链表SL中各结点的指针值调整记录位置,使得SL中记录按关键字非递减有序排列 inti,p,q; SLNodet; p=SL.r[0].next;//p指示第一个记录的当前位置 printf("%d",SL.length); for(i=1;i { //SL.r[i...i-1]中记录已按关键字有序排列,第i个记录在SL中的当前记录不应小于i while(p p=SL.r[p].next;//找到第i个记录,并用p指示其在SL中当前位置 q=SL.r[p].next;//q指示当前未调整的表尾 if(p! =i){ t=SL.r[p];//交换记录,使第i个记录到位 SL.r[p]=SL.r[i]; SL.r[i]=t; SL.r[i].next=p;//指向被移走的记录,使得以后可由while循环找回 } p=q;//p指示未调整的表尾,为找到第i+1个记录作准备 //print(SL); //printf("\n"); } } /*************************************冒泡排序***********************/ voidbubble_sort(SqList&L) {//冒泡排序 inti; intk; RedTypetem; for(i=L.length-1,k=1;i>=1&&k;--i) { k=0; for(intj=1;j<=i;++j) { if(L.r[j].key>L.r[j+1].key) { tem=L.r[j]; L.r[j]=L.r[j+1]; L.r[j+1]=tem; k=1; } } } } /************************************快速排序**************************/ intPartition(SqList&L,intlow,inthigh) {//快速排序递归函数的实现 intpivotkey; L.r[0]=L.r[low]; pivotkey=L.r[low].key; while(low { while(low --high; L.r[low]=L.r[high]; while(low ++low; L.r[high]=L.r[low]; } L.r[low]=L.r[0]; returnlow; } /********************************简单选择排序***********************/ intSelectMinKey(SqList&L,inti) { intj,k=i; for(j=i+1;j { if(L.r[k].key>L.r[j].key) k=j; } returnk; } voidSelect_Sort(SqList&L) { inti,j; RedTypetem; for(i=1;i { j=SelectMinKey(L,i); if(i! =j) { tem=L.r[i]; L.r[i]=L.r[j]; L.r[j]=tem; } } } /**************************************堆排序*************************/ voidHeapAdjust(HeadType&L,ints,intm) {//对生成的堆进行排序,生成大顶堆 RedTyperc; rc=L.r[s]; intj; for(j=2*s;j<=m;j*=2) { if(j j++; if(rc.key>=L.r[j].key) break; L.r[s]=L.r[j]; s=j; } L.r[s]=rc; } voidHeadSort(HeadType&L) {//对一组无序的数字进行排序生成堆 inti; RedTypetemp; for(i=L.length/2;i>0;--i) HeapAdjust(L,i,L.length); for(i=L.length;i>1;--i) { temp=L.r[1]; L.r[1]=L.r[i]; L.r[i]=temp; HeapAdjust(L,1,i-1); } } /**************************************归并排序***************************/ voidMerge(RedTypeSR[],RedTypeTR[],ints,intm,intt) {//printf("+_+_+_+_+_+_"); inti,j,k; //RcdType*tem; for(j=m+1,k=s,i=s;i<=m&&j<=t;k++) { if(SR[i].key TR[k]=SR[i++]; else TR[k]=SR[j++]; } while(i<=m) { //for(l=0;l TR[k++]=SR[i++]; } while(j<=t) { //for(l=0;l TR[k++]=SR[j++]; } } voidMSort(RedTypeSR[],RedTypeTR1[],ints,intt) { intm; RedTypeTR2[MAXSIZE+1]; if(s==t) TR1[s]=SR[s]; else { m=(s+t)/2; MSort(SR,TR2,s,m); MSort(SR,TR2,m+1,t); Merge(TR2,TR1,s,m,t); } } voidMergeSort(SqList&L) { MSort(L.r,L.r,1,L.length); } /************************************基数排序*************************/ oidInitList(SLList&L,RedTypeD[],intn)//初始化静态链表L(把数组D中的数据存于L中) { charc[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY]; inti,j,max=D[0].key;//max为关键字的最大值 for(i=1;i if(max max=D[i].key; L.keynum=int(ceil(log10(max))); L.recnum=n; for(i=1;i<=n;i++) { L.r[i].otheritems=D[i-1].otherinfo; itoa(D[i-1].key,c,10);//将10进制整型转化为字符型,存入c for(j=strlen(c);j { strcpy(c1,"0"); strcat(c1,c); strcpy(c,c1); } for(j=0;j } } voidDistribute(SLCellr[],inti,ArrTypef,ArrTypee)//算法10.15 {//静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。 本算法按 //第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。 //f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录 intj,p; for(j=0;j for(p=r[0].next;p;p=r[p].next) { j=r[p].keys[i]-'0';//将记录中第i个关键字映射到[0..RADIX-1] if(! f[j]) f[j]=p; else r[e[j]].next=p; e[j]=p;//将p所指的结点插入第j个子表中 } } voidCollect(SLCellr[],ArrTypef,ArrTypee)//算法10.16 //本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成 //一个链表,e[0..RADIX-1]为各子表的尾指针。 {intj,t; for(j=0;! f[j];j=++j);//找第一个非空子表 r[0].next=f[j]; t=e[j];//r[0].next指向第一个非空子表中第一个结点 while(j {for(j=++j;j f[j];j=++j);//找下一个非空子表 if(f[j])//链接两个非空子表 {r[t].next=f[j]; t=e[j]; } } r[t].next=0;//t指向最后一个非空子表中的最后一个结点 } voidprintl(SLListL)//按链表输出静态链表 {inti=L.r[0].next,j; while(i) {for(j=L.keynum-1;j>=0;j--)printf("%c",L.r[i].keys[j]); printf(""); i=L.r[i].next; } } voidRadixSort(SLList&L)//算法10.17 //L是采用静态链表表示的顺序表。 对L作基数排序,使得L成为按关键字 //自小到大的有序静态链表,L.r[0]为头结点。 {inti; ArrTypef,e; for(i=0;i L.r[L.recnum].next=0;//将L改造为静态链表 for(i=0;i {Distribute(L.r,i,f,e);//第i趟分配 Collect(L.r,f,e);//第i趟收集 printf("第%d趟收集后: \n",i+1); printl(L); printf("\n"); } } voidprint(SLListL)//按数组序号输出静态链表 {inti,j; printf("keynum=%drecnum=%d\n",L.keynum,L.recnum); for(i=1;i<=L.recnum;i++) {printf("keys="); for(j=L.keynum-1;j>=0;j--)printf("%c",L.r[i].keys[j]); printf("otheritems=%dnext=%d\n",L.r[i].otheritems,L.r[i].next); } } voidSort(SLListL,intadr[])//改此句(类型) //求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号 {inti=1,p=L.r[0].next; while(p) {adr[i++]=p; p=L.r[p].next; } } voidRearrange(SLList&L,intadr[])//改此句(类型) //adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。 //本算法按adr重排L.r,使其有序。 算法10.18(L的类型有变) {inti,j,k; for(i=1;i if(adr[i]! =i) {j=i; L.r[0]=L.r[i];//暂存记录L.r[i] while(adr[j]! =i)//调整L.r[adr[j]]的记录到位直到adr[j]=i为止 {k=adr[j]; L.r[j]=L.r[k]; adr[j]=j; j=k;//记录按序到位 } L.r[j]=L.r[0]; adr[j]=j; } } 运行效果图: 七【上机实验中的其他它问题及心得】 (在上机实验中遇到的你不能解决的其它问题,简单描述一下你此次上机的收获及感想) 心得: 排序时计算机程序设计中的一种重要的操作,因为我们无论做什么样的程序都会涉及到排序算法,在第十章的内部排序算法中,基本上都是一些经典的排序算法,这是我选择这个题目的主要原因,因为通过这个综合设计,我可以了解不同的排序算法,根据不同的情况,选择更好的算法。 在本章中共有12种算法: 插入排序5种,选择排序3种,快速排序2种,归并排序和基数排序。 在没有接触本章之前,我们只是接触了简单的冒泡排序和选择排序,这些只是对数n不是很大的情况,当n值很大时,我们果继续使用这些简单的算法,时间复杂度会很大的。 因此,在本章中介绍的这些算法,适合我们遇到的任何情况,不能够说那种算法是好的,不同的算法都有好坏,我们可以根据不同的情况,从这些算法中选择合适的算法。 每一种排序都有最好的情况和最坏的情况。 1.从平均时间性能而言,快速排序是最好的,因为其所用的时间是最少的。 但是,如果想到最坏的情况,当然就要考虑到堆排序和归并排序。 堆排序对n值较大时是比较有效的,因为堆排序主要的耗时是在建初始堆和调整建新堆时进行的反复的“筛选”。 当n值很大时,归并排序所需时间较堆排序省,但是归并排序所需要的辅助空间较多。 入过在输入一行数字是,这些数字是基本有序的,为了节省时间和空间,可以选择冒泡排序和简单选择排序。 从方法的稳定性来说: 基数排序时稳定的内部排序算法,所有时间复杂度为O(n^2)的简单排序法也是稳定的,但是,快速排序、堆排序和希尔排序等时间较好的排序方法都是不稳定的。 一般来说,排序过程中的“比较“是在“相邻两个关键字”间进行的排序方法是稳定的。 因此,在所有的算法当中,没有哪一种算法是绝对最优的。 有的适用于n较大时,有的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 内部 排序 12 算法 上机 实验 报告 word 文档 良心 出品