数据结构习题解析与实训 第九章.docx
- 文档编号:12287096
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:30
- 大小:21.78KB
数据结构习题解析与实训 第九章.docx
《数据结构习题解析与实训 第九章.docx》由会员分享,可在线阅读,更多相关《数据结构习题解析与实训 第九章.docx(30页珍藏版)》请在冰豆网上搜索。
数据结构习题解析与实训第九章
第
9
章内部排序
以下内部排序的各种算法中,排序对象的数据元素表采用顺序存储结构。
为简单起
见,表的最大容量为100,每个元素只包含一个字段即关键字段,且关键字都是整型值。
排序表的结构如下所示。
#define KEYTYPE int
#define MAXSIZE 100
typedef struct
{KEYTYPE key;
}RECNODE;
RECNODE a[MAXSIZE];
9.1
习题解析
【习题
1
】 直接插入排序
题目要求:
将输入的若干个整数按直接插入排序算法从小到大排序,数据从数组的1
单元放起。
【解答】
#include ″datastru.h″
#include
voidinsertsort(RECNODE*r,intn)
{/*直接插入排序*/
inti,j;
for(i=2;i<=n;i++)
{[0]=r[i];j=i-1; /*r[0]是监视哨,j表示当前已排好序列的长度*/
l110
数据结构习题解析与实训
while(r[0].key {r[j+1]=r[j]; j--;} r[j+1]=r[0];/*元素插入*/ } } main() {ECNODE a[MAXSIZE]; int i,j,k,len; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;a[k].key=j;scanf(″%d″,&j);} len=k; printf(″\n排序前: ″); for(i=0;i printf(″\n″); insertsort(a,len); printf(″\n\n排序后: ″); for(i=0;i printf(″\n\n″); } 【习题 2 】 冒泡排序 题目要求: 将输入的若干个整数按冒泡排序算法从小到大排序,数据从数组的1单 元放起。 【解答】 #include ″datastru.h″ #include voidbublesort(RECNODE*r,intn) {/*简单交换排序: 冒泡排序*/ inti,j; RECNODEtemp; for(i=1;i for(j=n-1;j>=i;j--) if(r[j+1].key {temp=r[j+1]; r[j+1]=r[j]; r[j]=temp;} } main() {ECNODE a[MAXSIZE]; 第9章 内部排序 l111 int i,j,k,len; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;a[k].key=j;scanf(″%d″,&j);} len=k; printf(″\n排序前: ″); for(i=0;i printf(″\n″); bublesort(a,len); printf(″\n\n排序后: ″); for(i=0;i printf(″\n\n″); } 【习题 3 】 简单选择排序 题目要求: 将输入的若干个整数按简单选择排序算法从小到大排序,数据从数组的1 单元放起。 【解答】 #include ″datastru.h″ #include voidselesort(RECNODE*r,intn) {/*简单选择排序*/ inti,j,k; RECNODEtemp; for(i=1;i {=i; /*k: 最小关键字的初始位置*/ for(j=i+1;j<=n;j++) if(r[j].key k=j;/*k: 跟踪记录当前最小关键字的位置*/ if(k! =i)/*最小关键字元素和待排序列的第一个元素交换*/ {temp=r[i]; r[i]=r[k]; r[k]=temp;} } } main() {ECNODE a[MAXSIZE]; int i,j,k,len; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); l112 数据结构习题解析与实训 while(j! =0){k++;a[k].key=j;scanf(″%d″,&j);} len=k; printf(″\n排序前: ″); for(i=0;i printf(″\n″); selesort(a,len); printf(″\n\n排序后: ″); for(i=0;i printf(″\n\n″); } 【习题 4 】 快速排序 题目要求: 将输入的若干个整数按快速排序算法从小到大排序,数据从数组的1单 元放起。 【解答】 #include ″datastru.h″ #include intpartition(RECNODE*r,int*low,int*high) {/*一趟快速排序,返回枢轴位置,产生两个独立的待排子序列*/ inti,j; RECNODEtemp; i=*low; j=*high; temp=r[i]; /*枢轴记录保存在temp变量中*/ do{hile((r[j].key>=temp.key)&&(i if(i while((r[i].key<=temp.key)&&(i if(i }while(i! =j); r[i]=temp;/*枢轴记录的排序位置确定在i*/ returni; } voidquicksort(RECNODE*r,intstart,intend) {/*快速排序*/ inti; if(start {i=partition(r,&start,&end);/*一趟快速排序,返回枢轴位置,产生两个独立的待排子 序列*/ quicksort(r,start,i-1);/*对两个独立的待排子序列分别递归调用快速排序算法*/ 第9章 内部排序 l113 quicksort(r,i+1,end);} } main() {ECNODE a[MAXSIZE]; int i,j,k,len,start; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;a[k].key=j;scanf(″%d″,&j);} len=k;start=1; printf(″\n排序前: ″); for(i=0;i printf(″\n″); quicksort(a,start,len); printf(″\n\n排序后: ″); for(i=0;i printf(″\n\n″); } 【习题 5 】 堆排序 题目要求: 将输入的若干个整数按堆排序算法从小到大排序,数据从数组的1单元 放起。 【解答】 #include ″datastru.h″ #include voidsift(RECNODE*r,inti,intm) {/*i是根结点编号,m是以i结点为根的子树中最后一个结点的编号*/ intj; RECNODEtemp; temp=r[i]; j=2*i; /*j为i根结点的左孩子*/ while(j<=m) {if(j j++;/*当i结点有左右孩子时,j取关键字大的孩子结点编号*/ if(temp.key {r[i]=r[j]; i=j; j=2*i;} /*按堆定义调整,并向下一层筛选调整*/ else break;/*筛选调整完成,跳出循环*/ } r[i]=temp; l114 数据结构习题解析与实训 } voidheapsort(RECNODE*r,intn) {/*堆排序: n为r表中记录数,元素从r[1]开始放起*/ inti; RECNODEtemp; for(i=n/2;i>=1;i--) sift(r,i,n); /*将无序序列建成大堆*/ for(i=n;i>=2;i--) {temp=r[1];/*堆顶及堆尾元素交换*/ r[1]=r[i]; r[i]=temp; sift(r,1,i-1);/*交换后,从第一个元素开始调整为大堆,每次要处理的记录个数少一个*/ } } main() {ECNODE a[MAXSIZE]; int i,j,k,len; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;a[k].key=j;scanf(″%d″,&j);} len=k; printf(″\n排序前: ″); for(i=0;i printf(″\n″); heapsort(a,len); printf(″\n\n排序后: ″); for(i=0;i printf(″\n\n″); } 【习题 6 】 二路归并排序 题目要求: 将输入的若干个整数按二路归并排序算法从小到大排序,数据从数组的0 单元放起。 【解答】 #include ″datastru.h″ #include voidmerge(RECNODE*r,intlow,intm,inthigh) {/*两相邻的有序表(一个从low到m;另一个从m+1到high)合并为一个有序表(从low到 第9章 内部排序 l115 high)*/ RECNODE r1[MAXSIZE]; /*合并时用的缓冲向量*/ inti,j,k; i=low; j=m+1; k=0; while(i<=m&&j<=high)/*两相邻的有序表合并*/ if(r[i].key<=r[j].key) {r1[k]=r[i]; i++; k++;} else {r1[k]=r[j]; j++; k++;} while(i<=m)/*有序表剩余部分处理*/ {r1[k]=r[i]; i++; k++;} while(j<=high)/*有序表剩余部分处理*/ {r1[k]=r[j]; j++; k++;} for(i=low,k=0;i<=high;i++,k++)/*缓冲向量r1复制到原来的r中*/ r[i]=r1[k]; } voidmerge_one(RECNODE*r,intlenth,intn) {/*二路归并中的″一趟归并″算法*/ inti=0; while(i+2*lenth-1 {merge(r,i,i+lenth-1,i+2*lenth-1); /*两子序列长度相等的*/ i=i+2*lenth;}/*情况下调用merge*/ if(i+lenth-1 merge(r,i,i+lenth-1,n-1);/*序列中的余留部分处理*/ } voidmergesort(RECNODE*r,intn) {/*二路归并排序算法*/ intlenth=1; /*有序子序列长度初始值=1*/ while(lenth {merge_one(r,lenth,n);/*调用″一趟归并″的算法*/ lenth=2*lenth;}/*有序子序列长度加倍*/ } main() {ECNODE a[MAXSIZE]; int i,j,k,len; l116 数据结构习题解析与实训 printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;a[k-1].key=j;scanf(″%d″,&j);} len=k; printf(″\n排序前: ″); for(i=0;i printf(″\n″); mergesort(a,len); printf(″\n″); printf(″\n\n排序后: ″); for(i=0;i printf(″\n″); } 【习题 7 】 排序综合练习 这是一个将上面的各个排序算法合并在一个综合程序中的练习,读者可通过菜单选 择方式运行各个排序算法。 【解答】 #include #include ″datastru.h″ intcreateList(RECNODE*r) {ntj,k; printf(″\n\n输入待排序数据(整数,以空格隔开,′0′结束): ″);k=0;scanf(″%d″,&j); while(j! =0){k++;r[k].key=j;scanf(″%d″,&j);} returnk; } frontdisplayList(RECNODE*r,intn) {nti; printf(″\n排序前: ″); for(i=0;i printf(″\n\n″); } reardisplayList(RECNODE*r,intn) {nti; printf(″\n\n排序后: ″); 第9章 内部排序 l117 for(i=0;i printf(″\n\n″); } voidinsertsort(RECNODE*r,intn) {/*直接插入排序*/ inti,j; for(i=2;i<=n;i++) {[0]=r[i]; j=i-1; /*r[0]是监视哨,j表示当前已排好序列的长度*/ while(r[0].key {r[j+1]=r[j]; j--;} r[j+1]=r[0];/*元素插入*/ } } voidbublesort(RECNODE*r,intn) {/*简单交换排序: 冒泡排序*/ inti,j; RECNODEtemp; for(i=1;i for(j=n-1;j>=i;j--) if(r[j+1].key {temp=r[j+1]; r[j+1]=r[j]; r[j]=temp;} } intpartition(RECNODE*r,int*low,int*high) {/*一趟快速排序,返回i,产生了两个独立的待排子序列*/ inti,j; RECNODEtemp; i=*low; j=*high; temp=r[i]; /*枢轴记录保存在temp变量中*/ do{hile((r[j].key>=temp.key)&&(i if(i while((r[i].key<=temp.key)&&(i if(i }while(i! =j); r[i]=temp;/*枢轴记录的排序位置确定在i*/ returni; } l118 数据结构习题解析与实训 voidquicksort(RECNODE*r,intstart,intend) {/*快速排序*/ inti; if(start {i=partition(r,&start,&end); /*一趟快速排序,返回i,产生了两个独立的待排子序列*/ quicksort(r,start,i-1);/*对两个独立的待排子序列分别递归调用快速排序算法*/ quicksort(r,i+1,end);} } voidselesort(RECNODE*r,intn) {/*简单选择排序*/ inti,j,k; RECNODEtemp; for(i=1;i {=i; /*k: 最小关键字的初始位置*/ for(j=i+1;j<=n;j++) if(r[j].key k=j;/*k: 跟踪记录当前最小关键字的位置*/ if(k! =i)/*最小关键字元素和待排序列的第一个元素交换*/ {temp=r[i]; r[i]=r[k]; r[k]=temp;} } } voidsift(RECNODE*r,inti,intm) {/*i是根结点编号,m是以i结点为根的子树中最后一个结点的编号*/ intj; RECNODEtemp; temp=r[i]; j=2*i;/*j为i根结点的左孩子*/ while(j<=m) {if(j j++; /*当i结点有左右孩子时,j取关键字大的孩子结点编号*/ if(temp.key {r[i]=r[j]; i=j; j=2*i;}/*按堆定义调整,并向下一层筛选调整*/ else break;/*筛选调整完成,跳出循环*/ } r[i]=temp; } 第9章 内部排序 l119 voidheapsort(RECNODE*r,intn) {/*堆排序: n为r表中记录数,元素从r[1]开始放起*/ inti; RECNODEtemp; for(i=n/2; i>=1; i--) sift(r,i,n);/*将无序序列建成大堆*/ for(i=n; i>=2; i--) {temp=r[1];/*堆顶及堆尾元素交换*/ r[1]=r[i]; r[i]=temp; sift(r,1,i-1); /*交换后,从第一个元素开始调整为大堆,每次要处理的记录个数减 少一个*/ } } voidmerge(RECNODE*r,intlow,intm,inthigh) {/*两相邻的有序表(一个从low到m;另一个从m+1到high)合并为一个有序表(从low到 high)*/ RECNODE r1[MAXSIZE];/*合并时用的缓冲向量*/ inti,j,k; i=low; j=m+1; k=0; while(i<=m&&j<=high)/*两相邻的有序表合并*/ if(r[i].key<=r[j].key) {r1[k]=r[i]; i++; k++;} else {r1[k]=r[j]; j++; k++;} while(i<=m)/*有序表剩余部分处理*/ {r1[k]=r[i]; i++; k++;} while(j<=high)/*有序表剩余部分处理*/ {r1[k]=r[j]; j++; k++;} for(i=low,k=0;i<=high;i++,k++) /*缓冲向量r1复制到原来的r中*/ r[i]=r1[k]; } voidmerge_one(RECNODE*r,intlenth,intn) {/*二路归并中的″一趟归并″算法*/ inti=0; while(i+2*lenth-1 l120 数据结构习题解析与实训 {merge(r,i,i+lenth-1,i+2*lenth-1); /*两子序列长度相等的*/ i=i+2*lenth;}/*情况下调用merge*/ if(i+lenth-1 merge(r,i,i+lenth-1,n-1);/*序列中的余留部分处理*/ } voidmergesort(RECNODE*r,intn) {/*二路归并排序算法*/ intlenth=1;/*有序子序列长度初始值=1*/ while(lenth {merge_one(r,lenth,n);/*调用″一趟归并″的算法*/ lenth=2*lenth;}/*有序子序列长度加倍*/ } voidmain(){ RECNODE a[MAXSIZE]; intlen,b,j,k; intloop=1; while(loop){ printf(″\n\n排序综合练习\n\n″); printf(″ 0--退出\n″); printf(″ 1--直接插入排序\n″); printf(″ 2--简单交换(冒泡)排序\n″); printf(″ 3--快速排序\n″); printf(″ 4--简单选择排序\n″); printf(″ 5--堆排序\n″); printf(″ 6--二路归并排序\n″); printf(″\n\n请选择项号: ″); scanf(″%d″,&b); printf(″\n\n″); if(b>=0&&b<=6) switch(b){ case0: loop=0; break;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构习题解析与实训 第九章 数据结构 习题 解析 第九