第十章排序参考答案

直到满足小堆定义或到达根结点。

(4)void MinMaxHeapIns(RecType R[],int n)

{ //假设R[1..n-1]是最小最大堆,插入第n个元素,把R[1..n]调成最小最大堆 j=n; R[0]=R[j];

h=?log2n?+1; //求高度

if (h%2==0) //插入元素在偶数层,是最大层

{i=n/2;

if (R[0].key

j=i/4;

while (j>0 && R[j]>R[i]) //调小堆 {R[i]=R[j]; i=j; j=i/4; } R[i]=R[0];

}

else //插入元素大于双亲,调大堆 {i=n; j=i/4;

while (j>0 && R[j]

}

else //插入元素在奇数层,是最小层 {i=n/2;

if (R[0].key>R[i].key) //插入元素大于双亲,先与双亲交换,然后调大堆 {R[j]=R[i]; j=i/4;

while (j>0 && R[j]

else //插入元素小于双亲,调小堆

{i=n; j=i/4;

while (j>0 && R[j]>R[i]) {R[i]=R[j]; i=j; j=i/4; }

R[i]=R[0]; }

}

}//MinMaxHeapIns

17.void BiInsertSort(RecType R[],int n)

{//二路插入排序的算法

int d[n+1]; //辅助存储 d[1]=R[1];first=1;final=1;

for(i=2;i<=n;i++)

{ if(R[i].key>=d[1].key) //插入后部 { low=1;high=final;

while (low<=high) //折半查找插入位置

{ m=(low+high)/2;

if(R[i].key< d[m].key) high=m-1; else low=m+1; }//while

for (j=final;j>=high+1;j--) d[j+1] = d[j];//移动元素 d[high+1]=R[i]; final++; //插入有序位置 }

else //插入前部

{ if(first==1){ first=n; d[n]=R[i];}

else{ low=first;high=n; while (low<=high)

{ m=(low+high)/2;

if(R[i].key< d[m].key) high=m-1; else low=m+1;

}//while

for (j=first;j<=high;j++) d[j-1] = d[j]; //移动元素 d[high]=R[i]; first--; }//if }//if }//for

R[1] =d[fisrt];

for(i=first%n+1,j=2;i!=fisrt;i=i%n+1,j++) R[j] =d[i]; //将序列复制回去 }//BiInsertSort

18. 手工模拟排序过程略。

#define n 待排序记录的个数 typedef struct

{ int key[d]; //关键字由d个分量组成 int next; //静态链域

AnyType other; //记录的其它数据域 } SLRecType;

SLRecType R[n+1]; //R[1..n]存放n个记录 typedef struct

{ int f,e; //队列的头、尾指针 } SLQueue;

SLQueue B[m] //用队列表示桶,共m个 int RadixSort(SLRecType R[], int n)

{ //对R[1..n]进行基数排序,返回收集用的链头指针

for(i=1;i

R[n].next=-1; p=1; //将初始链表的终端结点指针置空, p指向链表的第一个结点 for(j=d-1;j>=0;j--) //进行d趟排序

{for(i=0;i

if(B[k].f==-1) B[k].f=p; //将R[p]链到桶头 else R[B[k].e].next=p; //将R[p]链到桶尾 B[k].e=p; //修改桶的尾指针, p=R[p].next; //扫描下一个记录

}//while i=0;

while(B[i].f==-1) i++; //找第一个非空的桶

t=B[i].e; p=B[i].f //p为收集链表的头指针,t为尾指针 while(i

if(B[i].f!=-1){ R[t].next=B[i].f; t=B[i].e; } //连接非空桶

}//while

R[t].next=-1; //本趟收集完毕,将链表的终端结点指针置空 }//for return p;

}//RadixSort

19. [题目分析]本题是基数排序的特殊情况,关键字只含一位数字的整数。 typedef struct { int key; int next; } SLRecType; SLRecType R[N+1]; typedef struct { int,f,e; } SLQueue;

SLQueue B[10];

int Radixsort(SLRecType R[],int n) //设各关键字已输入到R数组中 {for (i=1;i

R[n].next=-1; p=1; //-1表示静态链表结束

for (i=0;i<=9;i++);{ B[i].f=-1; B[i].e=-1;} //设置队头队尾指针初值 while (p!=-1) //一趟分配

{k=R[p].key; //取关键字 if(B[k].f==-1)B[k].f=p; //修改队头指针 else R[B[k].e].next=p; B[k].e=p;

p=R[p].next; //下一记录 }

i=0; //一趟收集

while (B[i].f==-1) i++;

t=B[i].e; p=B[i]f; while (i<9) {i++;

if (B[i].f!=-1)

{ R[t].next=B[i].f;t=B[i].e;} }

R[t].next=-1;

return p; //返回第一个记录指针

}

[算法讨论]若关键字含d位,则要进行d趟分配和d趟收集。关键字最好放入字符数组,以便取关键字的某位。

20. void Adjust(int T[],int s)

{ //选得最小关键字记录后,从叶到根调整败者树,选下一个最小关键字 //沿从叶子结点R[s]到根结点T[0]的路径调整败者树

t=(s+k)/2; //T[t]是R[s]的双亲结点 while(t>0)

{ if(R[s].key>R[T[t]].key) s<-->T[t]; //s指示新的胜者 t=t/2; }//while T[0]=s; }//Adjust

void CreateLoserTree(int T[])

{ //建立败者树,已知R[0]到R[k-1]为完全二叉树T的叶子结点,存有k个关键字,沿 //从叶子到根的k条路径将T调整为败者树 R[k].key=MINKEY; //MINKEY是最小关键字 for(i=0;i

for(i=k-1;k>=0;i--) Adjust(T,i); }//CreateLoserTree

21、[题目分析]利用快速排序思想解决。由于要求“对每粒砾石的颜色只能看一次”,设3个指针i,j和k,分别指向红色、白色砾石的后一位置和待处理的当前元素。从k=n开始,从右向左搜索,若该元素是兰色,则元素不动,指针左移(即k-1);若当前元素是红色砾石,分i>=j(这时尚没有白色砾石)和i

为方便处理,将三种砾石的颜色用整数1、2和3表示。

void QkSort(rectype r[],int n)

// r为含有n个元素的线性表,元素是具有红、白和兰色的砾石,用顺序存储结构存储, //本算法对其排序,使所有红色砾石在前,白色居中,兰色在最后。 {int i=1,j=1,k=n,temp; while (k!=j)

{while (r[k].key==3) k--;// 当前元素是兰色砾石,指针左移 if (r[k].key==1) // 当前元素是红色砾石

联系客服:779662525#qq.com(#替换为@)