第九章习题.docx
- 文档编号:30561092
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:21
- 大小:56.78KB
第九章习题.docx
《第九章习题.docx》由会员分享,可在线阅读,更多相关《第九章习题.docx(21页珍藏版)》请在冰豆网上搜索。
第九章习题
第九章习题
9.1 以关键码序列(503,087,512,061,908,170,897,275,653,426)为例,手工执行以下排序算法,写出每一趟排序结束时的关键码状态:
(1)直接插入排序;
(2)希尔排序(增量d[1]=5);
(3)快速排序; (4)堆排序;
(5)归并排序; (6)基数排序。
9.2 一组关键字码,40,27,28,12,15,50,7,采用快速排序或堆排序,写出每趟排序结果。
9.3 不难看出,对长度为n的记录序列进行快速排序时,所需进行的比较次数依赖于这n个元素的初始排列。
n=7时在最好情况下需进行多少次比较?
请说明理由。
对n=7给出一个最好情况的初始排列实例。
9.4假设序列由n个关键字不同的记录构成,要求不经排序而从中选出关键字从大到小顺序的前k(k 试问如何进行才能使所作的关键字间比较次数达到最小? 9.5 插入排序中找插入位置的操作可以通过二分查找的方法来实现。 试据此写一个改进后的插入排序算法。 9.6 编写一个双向起泡的排序算法,即相邻两遍向相反方向起泡。 9.7编写算法,对n个关键字取整数值的记录序列进行整理,以使所有关键字为负值的记录排在关键字为非负值的记录之前,要求: 采取顺序存储结构,至多使用一个记录的辅助存储空间; 算法的时间复杂度O(n); 讨论算法中记录的最大移动次数。 9.8试以单链表为存储结构实现简单选择排序的算法 9.9假设含n个记录的序列中,其所有关键字为值介于v和w之间的整数,且其中很多关键字的值是相同的。 则可按如下方法排序: 另设数组number[v...w]且令number[i]为统计关键字取整数I的记录数,之后按number重排序列以达到有序,编写算法实现上述排序方法,并讨论此方法的优缺点。 9.10已知两个有序序列(a1,a2,...,am)和(am+1,am+2,...,an),并且其中一个序列的记录个数少于s,且s=? √n? . 试写一个算法,用O(n)时间和O (1)附加空间完成这两个有序序列的归并。 9.11偶交换排序如下所述: 第一趟对所有奇数i,将a[i]和a[i+1]进行比较;第二趟对所有偶数i,将a[i]和a[i+1]进行比较,若a[i]>a[i+1],则将两者交换;第一趟对所有奇数i,第二趟对所有偶数i,…,依次类推直至整个序列有序为止。 (1)这种排序方法的结束条件是什么? (2)分析当初始序列为正序或逆序两种情况下,奇偶交换排序过程中所需进行的关键字比较的次数。 (3)写出奇偶交换排序的算法。 9.12设计一个用链表表示的直接选择排序算法。 9.13插入排序中找插入位置的操作可以通过二分查找的方法来实现。 试据此写一个改进后的插入排序算法。 9.14一个线性表中的元素为正整数或负整数。 设计一个算法,将正整数和负整数分开,使线性表的前一半为负整数,后一半为正整数。 不要求对元素排序,但要尽量减少交换次数。 9.15为什么通常使用一维数组作为堆的存放形式? 9.16已知(k1,k2,…,kn)是堆,写一个算法将(k1,k2,…,kn,kn+1)调整为堆。 按此思想写一个从空堆开始一个一个添入元素的建堆算法。 9.17试比较直接插入排序、简单选择排序、快速排序、堆排序、归并排序、希尔排序和基数排序的时空性能、稳定性和适用情况。 9.18 在供选择的答案中填入正确答案: (1)、排序(分类)的方法有许多种: __A__法从未排序序列中依次取出元素,与排序序列(初始为空)中的元素作比较,将其放入已排序列的正确位置上;__B__法从未排序序列中挑选元素,并将其依次放入已排序序(初始时为空)的一端;交换排序法是对序列中元素进行一系列的比较,当被比较的两元素逆序时进行交换。 __C___和__D__是基于这类方法的两种排序方法,而__D__是比__C__效率更高的方法,利用某种算法,根据元素的关键值计算出排序位置的方法是__E__。 供选择答案 ① 选择排序 ② 快速排序 ③ 插入排序 ④ 冒泡排序 ⑤ 归并排序 ⑥ 二分排序 ⑦ 哈希排序 ⑧ 基数排序 (2)、一组记录的关键字为(46,79,56,38,40,84),利用快速排序的方法,以第一个记录为基准得到的一次划分结果为 。 A、38,40,46,56,79,84 B、40,38,46,79,56,84 C、40,38,46,56,79,84 D、40,38,46,84,56,79 (3)、下列排序算法中, 算法可能会出现下面情况: 初始数据有序时,花费时间反而最多。 A、堆排序 B、冒泡排序 C、快速排序 D、SHELL排序 9.19 判断正误: ()在一个大堆中,最小元素不一定在最后。 ()对n个记录采用快速排序方法进行排序,最坏情况下所需时间是o(nlog2n)。 ()在执行某排序算法过程中,出现了排序码朝着与最终排序序列相反方向移动的现象,则称该算法是不稳定的。 实习题 一、随机生成30个数,试比较直接插入排序、简单选择排序、起泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。 二、统计成绩。 给出n个学生的考试成绩表,每条信息由姓名与分数组成。 (1)按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次; (2)按名次列出每个学生的姓名与分数。 9.1 (1)无序表: 顺序查找不成功时,查找长度为n+1;成功时,平均查找长度为1/(n+1)*(1+2+…+(n+1))=(n+2)/2;两者不相同。 (2)表中只有一个关键字等于给定值k的记录,无序表、有序表: 顺序查找成功时,平均查找长度均为1/(n)*(1+2+…+n)=(n+1)/2;两者相同。 (3)表中只有m个关键字等于给定值k的记录,无序表: ASL=n+1;有序表: ASL=(n+1)/2+m;两者不相同。 9.3 ASL=1/10(1+2*2+4*3+3*4)=2.9 9.11 9.14 删除50后 删除68后 9.19 22 67 41 30 53 46 13 01 0 1 2 3 4 5 6 7 8 9 10 ASL=(4*1+2*2+3+6)/8=17/8 9.25 intSearch-Seq(SSTableST,KeyTypekey){ //在顺序表ST中顺序查找其关键字等于key的数据元素,ST按关键字自大至小有序, //若找到,则函数值为该元素在表中的位置,否则为0 ST.elem[ST.length+1].key=key; for(i=1;ST.elem[i].key>key;++i); if(ST.elem[i].key==key)&&(i<=ST.length)returni elsereturn0; }//Search-Seq 9.31 TelemTypeMaxv(BitreeT){ //返回二叉排序树T中所有结点的最大值 for(p=T;p->rchild;p=p->rchild); returnp->data; }//Maxv TelemTypeMinv(BitreeT){ //返回二叉排序树T中所有结点的最小值 for(p=T;p->lchild;p=p->lchild); returnp->data; }//Minv StatusIsBST(BitreeT){ //判别T是否为二叉排序树 if(! T)returnOK; elseif((! T->lchild)||((T->lchild)&&(IsBST(T->lchild)&&(Maxv(T->lchild) &&((! T->rchild)||((T->rchild)&&(IsBST(T->rchild)&&(Minv(T->rchild)>T->data))) returnOK elsereturnERROR; }//IsBST 9.33 StatusOutputGEx(BitreeT,TelemTypex){ //从大到小输出给定二叉排序树T中所有值不小于x的数据元素 if(T){ if(OutputGEx(T->rchild,x)) if(T->data>=x){ print(T->data); if(OutputGEx(T->lchild,x))returnOK; } elsereturnOK; } elsereturnOK; }//OutputGEx 第九章查找 9.25 intSearch_Sq(SSTableST,intkey)//在有序表上顺序查找的算法,监视哨设在高下标端 { ST.elem[ST.length+1].key=key; for(i=1;ST.elem[i].key>key;i++); if(i>ST.length||ST.elem[i].key returni; }//Search_Sq 分析: 本算法查找成功情况下的平均查找长度为ST.length/2,不成功情况下为ST.length. 9.26 intSearch_Bin_Digui(SSTableST,intkey,intlow,inthigh)//折半查找的递归算法 { if(low>high)return0;//查找不到时返回0 mid=(low+high)/2; if(ST.elem[mid].key==key)returnmid; elseif(ST.elem[mid].key>key) returnSearch_Bin_Digui(ST,key,low,mid-1); elsereturnSearch_Bin_Digui(ST,key,mid+1,high); } }//Search_Bin_Digui 9.27 intLocate_Bin(SSTableST,intkey)//折半查找,返回小于或等于待查元素的最后一个结点号 { int*r; r=ST.elem; if(key elseif(key>=r[ST.length].key)returnST.length; low=1;high=ST.length; while(low<=high) { mid=(low+high)/2; if(key>=r[mid].key&&key returnmid; elseif(key elselow=mid; }//本算法不存在查找失败的情况,不需要return0; }//Locate_Bin 9.28 typedefstruct{ intmaxkey; intfirstloc; }Index; typedefstruct{ int*elem; intlength; Indexidx[MAXBLOCK];//每块起始位置和最大元素,其中idx[0]不利用,其内容初始化为{0,0}以利于折半查找 intblknum;//块的数目 }IdxSqList;//索引顺序表类型 intSearch_IdxSeq(IdxSqListL,intkey)//分块查找,用折半查找法确定记录所在块,块内采用顺序查找法 { if(key>L.idx[L.blknum].maxkey)returnERROR;//超过最大元素 low=1;high=L.blknum; found=0; while(low<=high&&! found)//折半查找记录所在块号mid { mid=(low+high)/2; if(key<=L.idx[mid].maxkey&&key>L.idx[mid-1].maxkey) found=1; elseif(key>L.idx[mid].maxkey) low=mid+1; elsehigh=mid-1; } i=L.idx[mid].firstloc;//块的下界 j=i+blksize-1;//块的上界 temp=L.elem[i-1];//保存相邻元素 L.elem[i-1]=key;//设置监视哨 for(k=j;L.elem[k]! =key;k--);//顺序查找 L.elem[i-1]=temp;//恢复元素 if(k returnk; }//Search_IdxSeq 分析: 在块内进行顺序查找时,如果需要设置监视哨,则必须先保存相邻块的相邻元素,以免数据丢失. 9.29 typedefstruct{ LNode*h;//h指向最小元素 LNode*t;//t指向上次查找的结点 }CSList; LNode*Search_CSList(CSList&L,intkey)//在有序单循环链表存储结构上的查找算法,假定每次查找都成功 { if(L.t->data==key)returnL.t; elseif(L.t->data>key) for(p=L.h,i=1;p->data! =key;p=p->next,i++); else for(p=L.t,i=L.tpos;p->data! =key;p=p->next,i++); L.t=p;//更新t指针 returnp; }//Search_CSList 分析: 由于题目中假定每次查找都是成功的,所以本算法中没有关于查找失败的处理.由微积分可得,在等概率情况下,平均查找长度约为n/3. 9.30 typedefstruct{ DLNode*pre; intdata; DLNode*next; }DLNode; typedefstruct{ DLNode*sp; intlength; }DSList;//供查找的双向循环链表类型 DLNode*Search_DSList(DSList&L,intkey)//在有序双向循环链表存储结构上的查找算法,假定每次查找都成功 { p=L.sp; if(p->data>key) { while(p->data>key)p=p->pre; L.sp=p; } elseif(p->data { while(p->data L.sp=p; } returnp; }//Search_DSList 分析: 本题的平均查找长度与上一题相同,也是n/3. 9.31 intlast=0,flag=1; intIs_BSTree(BitreeT)//判断二叉树T是否二叉排序树,是则返回1,否则返回0 { if(T->lchild&&flag)Is_BSTree(T->lchild); if(T->data last=T->data; if(T->rchild&&flag)Is_BSTree(T->rchild); returnflag; }//Is_BSTree 9.32 intlast=0; voidMaxLT_MinGT(BiTreeT,intx)//找到二叉排序树T中小于x的最大元素和大于x的最小元素 { if(T->lchild)MaxLT_MinGT(T->lchild,x);//本算法仍是借助中序遍历来实现 if(last printf("a=%d\n",last); if(last<=x&&T->data>x)//找到了大于x的最小元素 printf("b=%d\n",T->data); last=T->data; if(T->rchild)MaxLT_MinGT(T->rchild,x); }//MaxLT_MinGT 9.33 voidPrint_NLT(BiTreeT,intx)//从大到小输出二叉排序树T中所有不小于x的元素 { if(T->rchild)Print_NLT(T->rchild,x); if(T->data printf("%d\n",T->data); if(T->lchild)Print_NLT(T->lchild,x);//先右后左的中序遍历 }//Print_NLT 9.34 voidDelete_NLT(BiTree&T,intx)//删除二叉排序树T中所有不小于x元素结点,并释放空间 { if(T->rchild)Delete_NLT(T->rchild,x); if(T->data q=T; T=T->lchild; free(q);//如果树根不小于x,则删除树根,并以左子树的根作为新的树根 if(T)Delete_NLT(T,x);//继续在左子树中执行算法 }//Delete_NLT 9.35 voidPrint_Between(BiThrTreeT,inta,intb)//打印输出后继线索二叉排序树T中所有大于a且小于b的元素 { p=T; while(! p->ltag)p=p->lchild;//找到最小元素 while(p&&p->data { if(p->data>a)printf("%d\n",p->data);//输出符合条件的元素 if(p->rtag)p=p->rtag; else { p=p->rchild; while(! p->ltag)p=p->lchild; }//转到中序后继 }//while }//Print_Between 9.36 voidBSTree_Insert_Key(BiThrTree&T,intx)//在后继线索二叉排序树T中插入元素x { if(T->data { if(T->rtag)//T没有右子树时,作为右孩子插入 { p=T->rchild; q=(BiThrNode*)malloc(sizeof(BiThrNode)); q->data=x; T->rchild=q;T->rtag=0; q->rtag=1;q->rchild=p;//修改原线索 } elseBSTree_Insert_Key(T->rchild,x);//T有右子树时,插入右子树中 }//if elseif(T->data>x)//插入到左子树中 { if(! T->lchild)//T没有左子树时,作为左孩子插入 { q=(BiThrNode*)malloc(sizeof(BiThrNode)); q->data=x; T->lchild=q; q->rtag=1;q->rchild=T;//修改自身的线索 } elseBSTree_Insert_Key(T->lchild,x);//T有左子树时,插入左子树中 }//if }//BSTree_Insert_Key 9.37 StatusBSTree_Delete_key(BiThrTree&T,intx)//在后继线索二叉排序树T中删除元素x { BTNode*pre,*ptr,*suc;//ptr为x所在结点,pre和suc分别指向ptr的前驱和后继 p=T;last=NULL;//last始终指向当前结点p的前一个(前驱) while(! p->ltag)p=p->lchild;//找到中序起始元素 while(p) { if(p->data==x)//找到了元素x结点 { pre=last; ptr=p; } elseif(last&&last->data==x)suc=p;//找到了x的后继 if(p->rtag)p=p->rtag; else { p=p->rchild; while(! p->ltag)p=p->lchild; }//转到中序后继 last=p; }//while//借助中序遍历找到元素x及其前驱和后继结点 if(! ptr)returnERROR;//未找到待删结点 Delete_BSTree(ptr);//删除x结点 if(pre&&pre->rtag) pre->rchild=suc;//修改线索 returnOK; }//BSTree_Delete_key voidDelete_BSTree(BiThrTree&T)//课本上给出的删除二叉排序树的子树T的算法,按照线索二叉树的结构作了一些改动 { q=T; if(! T->ltag&&T->r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第九 习题