数据结构课后习题答案第八章

  • 格式:doc
  • 大小:867.50 KB
  • 文档页数:9

第八章 排序(参考答案) 本章所用数据结构 #define N 待排序记录的个数 typedef struct { int key; ElemType other; }rectype; rectype r[n+1]; // r为结构体数组 8.2 稳定排序有:直接插入排序、起泡排序、归并排序、基数排序 不稳定排序有:希尔排序、直接选择排序、堆排序 希尔排序例:49,38, 49,90,70,25 直接选择排序例:2, 2,1 堆排序例:1,2,2

8.3 void StlinkedInsertSort(s , n); // 对静态链表s[1..n]进行表插入排序, 并调整结果,使表物理上排序 { #define MAXINT 机器最大整数 typedef struct { int key; int next; }rec; rec s[n+1]; // s为结构体数组 s[0].key=maxint; s[1].next=0; //头结点和第一个记录组成循环链表 i=2; //从第2个元素开始,依次插入有序链表中 while (i<=n) {q=0; p=s[0].next; // p指向当前最小元素,q是p的前驱 while (p!=0 && s[p].key { q=p; p=s[p].next; } s[i].next=p; s[q].next=i; // 将第个元素链入 i++; } // while(i<=n) 静态链表的插入 // 以下是重排静态链表,使之物理有序 i=1; p=s[0].next; while (i<=n) {WHILE (p q=s[p].next; if (i!=p) { s[i]s[p]; s[i].next=p; p=q; i++; } } 2

}//算法结束 8.4 void TwoWayBubbleSort( rectype r[n+1]; int n) // 对r[1..n]进行双向冒泡排序。即相邻两遍向两个相反方向起泡 { int i=1, exchange=1; // 设标记 while (exchange) { exchange=0; // 假定本趟无交换 for (j=n-i+1 j>=i+1;j--) // 向前起泡,一趟有一最小冒出 if (r[j]r[j-1]; exchange=1;} // 有交换 for (j= i+1;j>=n-I;j++) // 向后起泡,一趟有一最大沉底 if (r[j]>r[j+1]) {r[j]>r[j+1]; exchange=1;} // 有交换 i++; } // end of WHILE exchange }//算法结束 8.5 (1)在n=7时,最好情况下进行10次比较。6次比较完成第一趟快速排序,将序列分成 相等程度的序列(各3个元素),再各进行2次比较,完成全部排序。 (2)最好的初始排列:4,1,3,2,6,5,7

8.6 void QuickSort(rectype r[n+1]; int n) // 对r[1..n]进行快速排序的非递归算法 { typedef struct { int low,high; }node node s[n+1]; int top; int quickpass(rectype r[],int,int); // 函数声明 top=1; s[top].low=1; s[top].high=n; while (top>0) {ss=s[top].low; tt=s[top].high; top--; if (ss{ k=quickpass(r,ss,tt); if (k-ss>1) {top++; s[top].low=ss; s[top].high=k-1;} if (tt-k>1) {top++; s[top].low=k+1; s[top].high=tt;} } } // 算法结束 int quickpass(rectype r[];int s,t) {i=s; j=t; rp=r[i]; x=r[i].key; while (i {while (i if (i while (i=r[j].key) i++; if (i ] 3

r[i]=rp; return (i); } // 一次划分算法结束 8.7 void QuickSort(rectype r[n+1]; int n) // 对r[1..n]进行快速排序的非递归算法 对8.6算法的改进 { typedef struct { int low,high; }node node s[n+1]; int top; int quickpass(rectype r[],int,int); // 函数声明 top=1; s[top].low=1; s[top].high=n; ss=s[top].low; tt=s[top].high; top--; flag=true; while (flag || top>0) {k=quickpass(r,ss,tt); if (k-ss>tt-k) // 一趟排序后分割成左右两部分 {if (k-ss>1) // 左部子序列长度大于右部,左部进栈 {top++; s[top].low=ss; s[top].high=k-1; } if (tt-k>1) ss=k+1; // 右部短的直接处理 else flag=false; // 右部处理完,需退栈 } else if (tt-k>1) //右部子序列长度大于左部,右部进栈 {top=top+1; s[top].low=k+1; s[top].high=tt; } if (k-ss>1) tt=k-1 // 左部短的直接处理 else flag=false // 左部处理完,需退栈 } if (!flag && top>0) {ss=s[top].low; tt=s[top].high; top--; flag=true;} } // end of while (flag || top>0) } // 算法结束 int quickpass(rectype r[];int s,t) // 用“三者取中法”对8.6进行改进 { int i=s, j=t, mid=(s+t)/2; rectype tmp; if (r[i].key>r[mid].key) {tmp=r[i];r[i]=r[mid];r[mid]=tmp } if (r[mid].key>r[j].key) {tmp=r[j];r[j]=r[mid]; if (tmp>r[i]) r[mid]=tmp; else {r[mid]=r[i];r[i]=tmp } } {tmp=r[i];r[i]=r[mid];r[mid]=tmp } // 三者取中:最佳2次比较3次移动;最差3次比较10次移动 rp=r[i]; x=r[i].key; while (i {while (i4

if (i while (i=r[j].key) i++; if (i ] r[i]=rp; return (i); } // 一次划分算法结束 8.8 viod searchjrec(rectype r[],int j) //在无序记录r[n]中,找到第j(0<=j//轴元素的位置i,若i=j则查找结束。否则根据ji在0~i、1或i+1~n+1之间查 //找,直到/i=j为止。 { int quichpass (rectype r[],int,int) // 函数声明 i=quichpass(r,0,n-1); // 查找枢轴位置 whilehile(i!=j) if (jelse i=quichpass(r,i+1.n-1); }// searchjrec算法结束

8.9 viod rearrange (rectype r[],int n) //本算法重排具有n个元素的数r,使取负值的关键字放到取非负值的关键字之前。 { int i=0,j=n-1; rp=r[0]; while(i{while(i=0) j--; if(iwhile(iif(i}//while(i8.9 void arrange(rectype r[n+1]; int n) // 对r[1..n]进行整理,使关键字为负值的记录排在非负值的记录之前 [ int i=0, j=-1;rp=r[0]; while (i { while (i=0) j--; if (i while (i if (i } r[i]=rp;// }//算法结束 //本算法并未判断轴枢的关键字的正负,在排序中并未和轴枢 //记录比较,而是按正负区分,提高了效率 8.10