数据结构习题解析与实训 第九章.docx

上传人:b****4 文档编号:12287096 上传时间:2023-04-17 格式:DOCX 页数:30 大小:21.78KB
下载 相关 举报
数据结构习题解析与实训 第九章.docx_第1页
第1页 / 共30页
数据结构习题解析与实训 第九章.docx_第2页
第2页 / 共30页
数据结构习题解析与实训 第九章.docx_第3页
第3页 / 共30页
数据结构习题解析与实训 第九章.docx_第4页
第4页 / 共30页
数据结构习题解析与实训 第九章.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

数据结构习题解析与实训 第九章.docx

《数据结构习题解析与实训 第九章.docx》由会员分享,可在线阅读,更多相关《数据结构习题解析与实训 第九章.docx(30页珍藏版)》请在冰豆网上搜索。

数据结构习题解析与实训 第九章.docx

数据结构习题解析与实训第九章

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;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1