知识大全 数据结构第八章(排序)习题参考答案(下)

Posted 结点

篇首语:明明你一个人可以活的很开心的,偏偏非要学别人谈恋爱……本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 数据结构第八章(排序)习题参考答案(下)相关的知识,希望对你有一定的参考价值。

  二 算法设计题

   将哨兵放在R[n]中 被排序的记录放在R[ n ]中 重写直接插入排序算法

  解 重写的算法如下 因为哨兵换了位置 所以一切都反向了 有序区是从右边长出来的;

  void InsertSort(SeqList R)

   file://对 顺序表中记录R[ n ]按递增序进行插入排序

  int i j;

  for(i=n ;i>= ;i ) file://依 次插入R[n ] R[ ]

  if(R[i] key>R[i+ ] key) file://若 不是这样则R[i]原位不动

  

  R[n]=R[i];j=i+ ; file://R [n]是哨兵

  do file://从 左向右在有序区中查找插入位置

  R[j ]=R[j]; file://将 关键字小于R[i] key的记录向右移

  j++;

  while(R[j] key

  R[j ]=R[n]; file://将 R[i]插入到正确位置上

  //endif

  //InsertSort

   以单链表作为存储结构实现直接插入排序算法

  解 单链表?My God! 你还记得那是什么东东么? 先定义一个单链表结构吧

  #define int KeyType file://且 定义KeyType 为int型的吧

  typedef struct node

  KeyType key; file://关 键字域

  OtherInfoType info; file://其 它信息域 只是意思意思

  struct node * next; file://链 表中指针域

  RecNode; file://记 录结点类型

  typedef RecNode * RecList ; file://单 链表用RecList表示

  file://下 面就是排序算法

  void InsertSort(RecList R)

   file://链 式存储结构的直接插入排序算法

  file://R 是带头结点的单链表

  RecNode *p *q *s *t; file://这 四个指针用于保存排序时的结点位置

  s=R >next; file://s 指向第一个结点

  t=R; file://t 指向头结点

  p=R >next; file://前 一个记录

  q=P >next; file://下 一个记录

  while( q ) file://当 q为空时表示已经访问完毕所有结点 排序结束

  

  if(p >key>q >key)//此时前一关键字大于后一关键字 因此要进行插入操作

  

  while (s >key<=q >key&&s!=p)

   file://从 头向右逐个比较直到p结点

  t=s; file://记 下s结点位置

  s=s >next; file://指 针向右移

  //比较结束 找到比q >key大的第一个结点(记录)

  t >next=q; file://摘 下q所指结点 插入到相应位置

  P >next=q >next;

  q >next=s;

  q=p >next; file://恢 复指针顺序

  S=R >next;

  t=R;

  //endif

  else file://此 时没有插入操作 指针按序右移

  p=p >next; q=q >next;

  //endwhile

  //InsertSort

   设计一算法 使得在尽可能少的时间内重排数组 将所有取负值的关键字放在所有取非负值的关键字之前 请分析算法的时间复杂度

  解 因为只需将负数关键字排在前面而无需进行精确排列顺序 因此本算法采用两端扫描的方法 就象快速排序采用的方法一样 左边扫描到正数时停止 开始扫描右边 遇到负数时与左边的当前记录交换 如此交替进行 一趟下来就可以完成排序

  void ReSort(SeqList R)

  

  file://重 排数组 使负值关键字在前

  int i= j=n; file://数 组存放在R[ n]中

  while (i file://i

   while(i< ) href= file://遇 file://遇 到负数则继续扫描

  i++;

  R[ ]=R[i]; file://R [ ]为辅助空间

  while(i= )// 遇到正数则继续向左扫描

  j ;

  R[i++]=R[j];R[j ]=R[ ];//交换当前两个元素并移动指针

  //endwhile

  //ReSort

  本算法在任何情况下的比较次数均为n(每个元素和 )相比 交换次数少于n/ 总的来说 时间复杂度为O(n)

  * 写一个双向冒泡排序的算法 即在排序过程中交替改变扫描方向

  解 这个算法如下

  void BubbleSort(SeqList R)

   file://R [ n]是待排序文件 双向扫描冒泡排序

  int i j k;

  Boolean exchange; file://交 换标记

  for(i= ;i file://最 多只需(n/ )趟排序

  

  exchange=FLASE;

  for(j=n i; j>=i;j ) file://对 当前无序区R[i n i+ ]进行自下而上扫描

  

  if(R[j+ ] key file://轻 的泡泡上升

  

  R[ ]=R[j+ ];

  R[j+ ]=R[j];

  R[j]=R[ ];

  exchange=TURE; file://交 换后标记为真

  

  if (!exchange) return; file://本 趟排序未发生交换 提前结束

  //endfor

  exchange=FLASE; file://重 新设置标记

  for(k=i+ ; k<=n i;k++) file://对 当前无序区R[i n i+ ]进行自上而下扫描

  

  if(R[k+ ] key>R[k] key) file://重 的泡泡下沉

  

  R[ ]=R[k+ ];

  R[k+ ]=R[k];

  R[k]=R[ ];

  exchange=TURE; file://交 换后标记为真

  

  if(!exchange) return; file://本 趟未发生交换 提前结束

  //endfor

  //endfor

  //BubbleSort

   下面是一个自上往下扫描的冒泡排序的伪代码算法 它采用lastExchange 来记录每趟扫描中进行交换的最后一个元素的位置 并以它作为下一趟排序循环终止的控制值 请仿照它写一个自下往上扫描的冒泡排序算法

  void BubbleSort(int A[] int n)

  //不妨设A[ n ]是整型向量

  int lastExchange j i=n ;

  while (i> )

  lastExchange= ;

  for(j= ;j

  if([j+ ]

  交换A[j]和A[j+ ];

  lastExchange=j;

  

  i=lastExchange;//将i置为最后交换的位置

  //endwhile

  //BubbleSort

  解 算法如下 这种方向性的改变一般是一些加号要变为减号 大于变成小于 头一个结点变成最后一个结点 如此这般

  void BubbleSort(int A[] int n)

  file://不 妨设A[ n ]是整型向量

  int lastExchange j i= ;

  while (i file://这 一条很重要 如不改为这样 算法将无限循环下去

  lastExchange=n;

  for(j=n ;j>i;j )//从下往上扫描A[ i]

  if([j ]

  交换A[j]和A[j ];

  lastExchange=j;

  

  i=lastExchange;//将i置为最后交换的位置

  //endwhile

  //BubbleSort

   改写快速排序算法 要求采用三者取中的方式选择划分的基准记录;若当前被排序的区间长度小于等于 时 无须划分而是直接采用直接插入方式对其排序

  解 改写后的算法如下

  void QuickSort(SeqList R int low int high)

   file://对 R[low high]快速排序

  int pivotpos;

  if(high low<= ) file://若 当前区内元素少于 个

   file://则 进行直接插入排序

  InsertSort(R low high);//此函数就不写了

  

  else

  

  pivotpos=midPartion(R low high);

  QuickSort(R low pivotpos );

  QuickSort(R pivotpos+ high);

  

  //QuickSort

  int midPartion(SeqList R int i int j)

   file://三 者取中规则定基准

  if(R[(i+j)/ ] key>R[i] key)

   交换R[(i+j)/ ]和R[i];

  if(R[i] key>R[j] key)

   交换R[i]和R[j];

  if(R[i] key)

   交换R[i]和R[(i+j)/ ];

  file://以 上三个if语句就使区间的第一个记录的key值为三个key的中间值

  return Partion(R i j);//这样我们就可以仍使用原来的划分算法了

  

  顺便提一下 课本中又有几处笔误 如第 页的算法中A[i] A[k]应为R[i] R[k] 以及下面的算法中递归调用的应是RandomizedQuickSort函数而不是QuickSort函数

  另外 这些算法并不能直接用于验证 因为算法中用的都不是指针参数 而算法又要对实参进行修改才能达到所需结果 所以我们主要是要理解算法的整个思想和实现 真正编程的话 要上机多试才行

   对给定的j( ≤ j ≤ n ) 要求在无序的记录区R[ n]中找到按关键字自小到大排在第j个位置上的记录(即在无序集合中找到第j个最小元) 试利用快速排序的划分思想编写算法实现上述的查找操作

  (答案及点评) 以单链表为存储结构 写一个直接选择排序算法

相关参考

知识大全 数据结构复习总结第八章排序

  第八章排序  基本概念  文件有一组记录组成记录有若干数据项组成唯一标识记录的数据项称关键字;  排序是将文件按关键字的递增(减)顺序排列;  排序文件中有相同的关键字时若排序后相对次序保持不变的

知识大全 数据结构考研分类复习真题 第八章 答案[1]

  第八章 动态存储管理答案  一.选择题.C  二.判断题.错误   .正确  三.填空题  .()+=(%+=)   &nbs

知识大全 数据结构考研分类复习真题 第八章 答案[6]

  .()系统回收一个起始地址为大小为的空闲块后因右侧起始地址为空闲块应与之合并合并后起始地址为大小为的空闲块链表状态如图.()所示  .()  ()系统在接受存储块大小为的请求后将大小为的空闲块分出

知识大全 数据结构考研分类复习真题 第八章 答案[3]

  .首次拟合法从链表头指针开始查找找到第一个≥所需空间的结点即分配  最佳拟合法链表结点大小增序排列找到第一个≥所需空间的结点即分配  最差拟合法链表结点大小逆序排列总从第一个结点开始分配将分配后结

知识大全 数据结构考研分类复习真题 第八章 答案[5]

  .因为%+=所以和+=互为伙伴伙伴合并后首址为块大小为因为%+=所以所以首址大小为的块和首址大小为的块合并成为首址大小为的空闲块因为%+=其伙伴地址为=将其插入可利用空间表中回收后该伙伴系统的状态

知识大全 数据结构考研分类复习真题 第八章 答案[4]

  .因为=可利用空间表的初始状态图如所示  当用户申请大小为的内存块时因<<=但没有大小为的块只有大小为的块故将的块分裂成两个大小为的块其中大小为的一块挂到可利用空间表上另一块再分裂成两

知识大全 数据结构考研分类复习真题 第八章 答案[2]

  四.应用题  在伙伴系统中无论占用块或空闲块其大小均为的k(k为≥的正整数)次幂若内存容量为m则空闲块大小只能是…m由同一大块分裂而得的两个小块互称伙伴空间如内存大小为的块分裂成两个大小为的块只有

知识大全 自考知识点总汇之--数据结构导论(排序)

第八章排序cha138/Article/program/sjjg/201311/23009

知识大全 数据结构考研分类复习真题 第八章 动态存储管理[1]

  第八章动态存储管理  一选择题  动态存储管理系统中通常可有(   )种不同的分配策略【长沙铁道学院三(分)】  A.    

知识大全 数据结构考研分类复习真题 第八章 动态存储管理[4]

  .假设利用边界标识法并以首次拟合策略分配已知在某个时刻可利用空间表的状态如下图所示  (注存储块头部size域的值和申请分配的存储量均包括头部和尾部的存储空间)  请画出  ()当系统回收一个起始