《数据结构》课后习题答案及期末综合练习Word文档下载推荐.docx
- 文档编号:21725447
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:73
- 大小:256.58KB
《数据结构》课后习题答案及期末综合练习Word文档下载推荐.docx
《《数据结构》课后习题答案及期末综合练习Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《《数据结构》课后习题答案及期末综合练习Word文档下载推荐.docx(73页珍藏版)》请在冰豆网上搜索。
16,77,101,258,325,491[863,996,689,572]
第7趟:
16,77,101,258,325,491[572,689]863[996]
第8趟:
16,77,101,258,325,491,572[689]863[996]
第9趟:
16,77,101,258,325,491,572,689,863[996]
第10趟:
16,77,101,258,325,491,572,689,863,996
采用堆排序法排序时各趟的结果如下图所示:
(a)初始堆(b)建堆
(c)交换996和77,输出996(d)筛选调整
采用基数排序法排序时各趟的结果如下:
第1趟(按个位排序):
491,101,572,863,352,16,996,77,258,689
第2趟(按十位排序):
101,16,352,258,863,572,77,689,491,996
第3趟(按百位排序):
16,77,101,258,352,491,572,689,863,996
5.已知序列{86,94,138,62,41,54,18,32},请给出采用插入排序法对该序列作递增排序时,每一趟的结果。
采用插入排序法排序时各趟的结果如下:
(86),94,138,62,41,54,18,32
(86,94),138,62,41,54,18,32
(86,94,138),62,41,54,18,32
(62,86,94,138),41,54,18,32
(41,62,86,94,138),54,18,32
(41,54,62,86,94,138),18,32
(18,41,54,62,86,94,138),32
(18,32,41,54,62,86,94,138)
6.已知序列{27,35,11,9,18,30,3,23,35,20},请给出采用归并排序法对该序列作递增排序时的每一趟的结果。
采用归并排序法排序时各趟的结果如下:
27,35,11,9,18,30,3,23,35,20
[27,35][9,11][18,30][3,23][20,35]
[9,11,27,35][3,18,23,30][20,35]
[9,11,27,35][3,18,20,23,30,35]
[3,9,11,18,20,23,27,30,35,35]
二、算法设计题答案
1.二、算法设计题
1.一个线性表中的元素为全部为正或者负整数,试设计一算法,在尽可能少的时间内重排该表,将正、负整数分开,使线性表中所有负整数在正整数前面。
解:
本题的算法思想是:
设置两个变量分别指向表的首尾,它们分别向中间移动,指向表首的
如果遇到正整数,指向表尾的如果遇到负整数则互相交换,然后继续移动直至两者相遇。
实现本
题功能的算法如下:
voidpart(intarray[],intn)
{
inti,j;
i=1;
j=n;
while(i<
j)
{while(i<
j&
&
array[i]<
0)
i++;
while(i<
array[j]>
=0)
j--;
if(i<
{array[0]=array[i];
array[i]=array[j];
array[j]=array[0];
}
}
}
2.设计一个用单链表作存储结构的直接插入排序算法。
实现本题功能的算法如下:
voidinsertsort(node*head)
node*p,*q,*pre;
pre=head;
p=head->
next;
/*p指向待插入的元素*/
while(p!
=NULL)
q=head;
if(p->
key<
q->
key)/*插到表首*/
{pre->
next=p->
p->
next=head;
head=p;
else
{
while(q->
next!
=p&
q->
next->
p->
key)
q=q->
if(q->
next==p)
{
pre=p;
p=p->
}
else
{pre->
p->
next=q->
q->
next=p;
p=pre->
3.试设计一个算法实现双向冒泡排序。
(双向冒泡排序就是在排序的过程中交替改变扫描方向。
)
实现本题功能的算法如下:
voiddbubblesort(sqlistr,intn)
inti,j,flag;
flag=1;
while(flag!
flag=0;
for(j=i;
j<
n-i;
j++)
{
if(r[j]>
r[j+1])
flag=1;
r[0]=r[j];
r[j]=r[j+1];
r[j+1]=r[0];
for(j=n-i;
j>
i;
j--)
if(r[j]<
r[j-1])
{flag=1;
r[j]=r[j-1];
r[j-1]=r[0];
}
i++;
}
4.设一个一维数组A[n]中存储了n个互不相同的整数,且这些整数的值都在0到n-1之间,即A中存储了从0到n-1这n个整数。
试编写一算法将A排序,结果存放在数组B[n]中,要求算法的时间复杂性为O(n)。
解:
voidsort(intA[n],intB[n])
inti;
for(i=0;
i<
n;
i++)
B[A[i]]=A[i];
}
第九章
一、基础知识题
1.
(1)查找:
查找又称为查询或检索,是在一批记录中依照某个域的指定域值,找出相应的记录的操作。
(2)树型查找:
将原始数据表示成二叉排序树,树的每个结点对应一个记录,利用此二叉排序树进行类似于二分查找思想的数据查找,这种查找方法称为树型查找。
(3)平衡因子:
二叉树中每一结点的左子树高度减右子树高度为该结点的平衡因子。
(4)散列函数:
根据关键字求存储地址的函数称为散列函数。
(5)两个不同的关键字,其散列函数值相同,因而被映射到同一个表位置上的现象称为冲突。
2.设有序表为{a,b,c,d,e,f,g},请分别画出对给定值f,g和h进行拆半查找的过程。
查找f的过程如下:
查找成功,找到k=f值
查找g的过程如下:
查找成功,找到k=g值
查找h的过程如下:
3.试述顺序查找法、二分查找法和分块查找法对被查找表中元素的要求,每种查找法对长度为n的表的等概率查找长度是多少
顺序查找法:
表中元素可以任意存放。
查找成功的平均查找长度为(n+1)/2。
二分查找法:
表中元素必须以关键字的值递增或递减地存放且只能以顺序表存放。
查找成功的平均查找长度为log2(n+1)-1。
分块查找法:
表中每块内的元素可以任意存放,但块与块之间必须按关键字的大小递增或递减地存放,即前一块内所有元素的关键字不能大(或小)于后一块内任意一个元素的关键字。
若用顺序查找确定所在块,平均查找长度为1/2(n/s+s)+1;
若用二分查找确定所在块,平均查找长度为log2(n/s+1)+s/2。
4.设散列表长m=14,哈希函数为H(k)=kmod11,表中一共有8个元素{15,27,50,73,49,61,37,60},试画出采用二次探测法处理冲突的散列表。
采用二次探测法处理冲突的散列表如下:
5.线性表的关键字集合为{113,12,180,138,92,67,94,134,252,6,70,323,60},共有13个元素,已知散列函数为:
H(k)=kmod13,采用链接表处理冲突,试设计这种链表结构。
由题意,可得:
H(113)=113%13=9
H(12)=12%13=12
H(180)=180%13=11
H(138)=138%13=8
H(92)=92%13=1
H(67)=67%13=2
H(94)=94%13=3
H(134)=134%13=4
H(252)=252%13=5
H(6)=6%13=6
H(70)=70%13=5
H(323)=323%13=11
H(60)=60%13=8
链接表法的散列表如下图所示:
6.设关键字集合为{27,49,79,5,37,1,56,65,83},散列函数为:
H(k)=kmod7,散列表长度m=10,起始地址为0,分别用线性探测和链接表法来解决冲突。
试画出对应的散列表。
线性探测法的散列表如下图所示:
二、算法设计题
1.从小到大排列的,试写出对此链表的查找算法,并说明是否可以采用折半查找。
实现本题功能的算法如下,如果查找成功,则返回指向关键字为x的结点的指针,否则返回NULL。
node*sqsearch(node*head,intx)
node*p=head;
if(x>
p=p->
link;
elseif(x==p->
returnp;
else
p=NULL;
returnp;
虽然链表中的结点是按递增顺序排列的,但是其存储结构为单链表,查找结点时只能从头指针开始逐步进行搜索,所以不能用折半查找。
2.如果线性表中各结点查找概率不等,则可以使用下面的策略提高顺序表的查找效率:
如果找到指定的结点,则将该结点和其前趋(若存在)结点交换,使得经常被查找的结点尽量位于表的前端。
试对线性表的顺序存储结构和链式存储结构写出实现上述策略的顺序查找算法(注意查找时必须从表头开始向后扫描)。
采用顺序存储结构的算法如下,设记录存储在线性表的1~n单元中。
如果查找成功,返回关键字为k的记录在线性表中的位置,如果失败则返回0。
intseqsearch(sqlistr,intn,intk)
while((r[i].key!
=k)&
(i<
=n))
i++;
if(i<
=n)
r[0]=r[i];
r[i]=r[i-1];
r[i-1]=r[i];
i--;
return(i);
elsereturn(0);
采用链式存储结构的算法如下。
如果查找成功,则返回指向关键字为k的结点的指针,否则返回NULL。
node*seqsearch(node*head,intk)
if(head->
key==k)
return(head);
else
node*p,*q;
intx;
p=head;
q=head->
while(q!
=NULL&
key!
=k)
p=q;
q=q->
if(q!
=NULL)
x=p->
key;
key=q->
q->
key=x;
q=p;
return(q);
3.试设计一个在用开放地址法解决冲突的散列表上删除一个指定结点的算法。
首先计算要删除的关键字为k的记录所在的位置,将其置为空(即删除),然后利用线性探测法查找是否有与k发生冲突而存储到下一地址的记录,如果有则将记录移到原来k所在的位置,直至表中没有与k冲突的记录为止。
voiddelete(sqlistr,intn,intk)
{
inth,h0,h1;
h=k%n;
while(r[h].key!
h=(h+1)%n;
r[h]=NULL;
h0=h;
h1=(h+1)%n;
while(h1!
=h)
{while(r[h1].key%n!
h1=(h1+1)%n;
r[h0]=r[h1];
r[h1]=NULL;
h0=h1;
h1=(h1+1)%n;
4.设给定的散列表存储空间为H[1~m],每个单元可存放一个记录,H[i](1≤i≤m)的初始值为零,选取散列函数为H(R.key),其中key为记录R的关键字,解决冲突方法为线性探测法,编写一个函数将某记录R填入到散列表H中。
本题的算法思想:
先计算地址H(R.key),如果没有冲突,则直接填入;
否则利用线性探测法求出下一地址,直到找到一个为零的地址,然后填入。
实现本题功能的函数如下:
voidinsert(recordH,intm,recordR)
i=H(R.key);
if(H[i]==NULL)
H[i]=R;
while(H[i]!
i=(i+1)%(m+1);
第七章
一、基本知识题
1.图的逻辑结构特点是什么?
什么是无向图和有向图?
什么是子图?
什么是网络?
图是比树更为复杂的一种非线性数据结构,在图结构中,每个结点都可以和其它任何结点相连接。
无向图:
对于一个图G,若边集合E(G)为无向边的集合,则称该图为无向图。
有向图:
对于一个图G,若边集合E(G)为有向边的集合,则称该图为有向图。
子图:
设有两个图G=(V,E)和G’=(V’,E’),若V(G’)是V(G)的子集,且E(G’)是E(G)的子集,则称G’是G的子图(Subgraph)。
网络:
有些图,对应每条边有一相应的数值,这个数值叫做该边的权。
边上带权的图称为带权图,也称为网络。
2.什么是顶点的度?
什么是路径?
什么是连通图和非连通图?
什么是非连通图的连通分量?
顶点的度:
图中与每个顶点相连的边数,叫该顶点的度。
在一个图中,若从某顶点Vp出发,沿一些边经过顶点V1,V2,…,Vm到达,Vq,则称顶点序列(Vp,V1,V2,…,Vm,Vq)为从Vp到Vq的路径。
在无向图中,如果从顶点Vi到顶点Vj之间有路径,则称这两个顶点是连通的。
如果图中任意一对顶点都是连通的,则称此图是连通图。
非连通图的连通分量:
非连通图的每一个连通的部分叫连通分量。
3.给出图6.25所示的无向图G的邻接矩阵和邻接表两种存储结构。
图G所对应的邻接矩阵如下:
图G所对应的邻接表如下:
图25
4.假设图的顶点是A、B……请根据下面的邻接矩阵画出相应的无向图或有向图。
(a)所对应的无向图如下图(a)所示,(b)所对应的有向图如下图(b)所示:
5.
5.分别给出图6.26所示G图的深度优先搜索和广度优先搜索得到的顶点访问序列。
图26
深度优先搜索得到的顶点访问序列:
0、1、3、7、8、4、9、5、6、2;
广度优先搜索得到的顶点访问序列:
0、1、2、3、4、5、6、7、8、9。
6.应用prim算法求图6.27所示带权连通图的最小生成树。
该图的最小生成树如下:
图27
7.
写出图6.28所示有向图的拓朴排序序列
该有向图的拓朴排序序列为:
3、1、4、5、2、6。
二、算法设计题图28
1.如图6.29所示图G,试给出其对应的邻接表,并写出深度优先算法。
该图对应的邻接表如下:
深度优先算法:
voiddfsgraph(adjlistadj,intn)
/*深度优先遍历整个图*/
for(i=1;
=n;
i++)
visited[i]=0;
if(!
visited[i])
dfs(adj,i);
voiddfs(adjlistadj,intv)
/*以v为出发点,对图进行dfs遍历*/
{structedgenode*p;
visited[v]=1;
printf("
%d"
v);
p=adj[v]→link;
{if(visited[p→adjvex]==0)
dfs(adjlist,p→adjvex);
p=p→next;
2.如图6.29所示图G,试给出其对应的邻接矩阵,并写出广度优先算法。
该图对应的邻接矩阵如下:
广度优先算法:
voidbfsgraph(intadjarray[n][n],intn)
/*广度优先遍历整个图*/
i++)图29
bfs(adjarray,i);
voidbfs(intadjarray[][],intv)
/*以v为出发点,对图进行bfs遍历*/
queueq;
enqueue(&
q,v);
while(!
queueemty(&
q))
i=dequeue(&
q);
for(j=0;
j++)
if(adjarray[i][j]==1&
!
visited[j])
printf("
j);
visited[j]=1;
enqueue(&
q,j);
3.编写一个函数通过与用户交互建立一个有向图的邻接表。
voidcreategraph(adjlistg)
inte,i,s,d,n;
structedgenode*p;
请输入结点数(n)和边数(e):
\n"
);
scanf("
%d,%d"
&
n,&
e);
\n请输入第%d个顶点信息:
"
i);
%c"
g[i].data);
g[i].link=NULL;
=e;
{printf("
\n请输入第%d条边起点序号,终点序号:
scanf("
s,&
d);
p=(structedgenode*)malloc(sizeof(edgenode));
p→adjvex=d;
p→next=g[s].link;
g[s].link=p;
4.编写一个无向图的邻接矩阵转换成邻接表的算法。
逐个扫描邻接矩阵的各个元素,如第i行第j列的元素为1,则相应的邻接表的第i个单链表上增加一个j结点。
voidtransform(intadjarray[n][n],adjlistadj)
edgenode*p;
adj[i].data=i;
adj[i].link=NULL;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课后 习题 答案 期末 综合 练习