完整版数据结构c语言版课后习题答案完整版资料Word文件下载.docx
《完整版数据结构c语言版课后习题答案完整版资料Word文件下载.docx》由会员分享,可在线阅读,更多相关《完整版数据结构c语言版课后习题答案完整版资料Word文件下载.docx(18页珍藏版)》请在冰豆网上搜索。
本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。
因此可以考虑设头尾两个指针(i=1,j=n),从两
端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素
voidDelete(ElemTypeA[],intn)
//A是有n个元素的一维数组,本算法删除A中所有值为item的元素。
{i=1;
j=n;
//设置数组低、高端指针(下标)。
while(i<
j)
{while(i<
j&
&
A[i]!
=item)i++;
/若值不为item,左移指针。
if(i<
j)while(i<
A[j]==item)j--;
/若右端元素值为item,指针左移if(i<
j)A[i++]=A[j--];
}
[算法讨论]因元素只扫描一趟,算法时间复杂度为O(n)。
删除元素未使用其它辅助
空间,最后线性表中的元素个数是j。
第3章栈和队列
1.选择题
CCDAADABCDDDBCB
2.算法设计题
(2)回文是指正读反读均相同的字符序列,如“abba"
和“abdba"
均是回文,但“good”
不是回文。
试写一个算法判定给定的字符向量是否为回文。
(提示:
将一半字符入栈)
根据提示,算法可设计为:
//以下为顺序栈的存储结构定义
#defineStackSize100//假定预分配的栈空间最多为100个元素
typedefcharDataType;
//假定栈元素的数据类型为字符
typedefstruct{
DataTypedata[StackSize];
inttop;
}SeqStack;
intIsHuiwen(char*t)
{//判断t字符向量是否为回文,若是,返回1,否则返回0
SeqStacks;
inti,len;
chartemp;
InitStack(&
s);
len=strlen(t);
//求向量长度
for(i=0;
i<
len/2;
i++)//将一半字符入栈
Push(&
s,t[i]);
while(!
EmptyStack(&
s))
{//每弹出一个字符与相应字符比较
temp=Pop(&
if(temp!
=S[i])return0;
//不等则返回0
elsei++;
return1;
//比较完毕均相等则返回1
(7)假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag==0和tag==1来区别在队头指针(front)和队尾指针(rear)相等时,队列状态为空”还是满”试编写与此结构相应的插入(enqueue)和删除(dlqueue)算法。
【解答】
循环队列类定义
#include<
assert.h>
template<
classType>
classQueue{//循环队列的类定义
public:
Queue(int=10);
~Queue(){delete[]Q;
}
voidEnQueue(Type&
item);
TypeDeQueue();
TypeGetFront();
voidMakeEmpty(){front=rear=tag=0;
}//置空队列
intIsEmpty()const{returnfront==rear&
tag==0;
}//判队列空否
intIsFull()const{returnfront==rear&
tag==1;
}//判队列满否
private:
intrear,front,tag;
Type*Q;
//队尾指针、队头指针和队满标志//存放队列元素的数组
构造函数template<
Queue<
Type>
:
Queue(intsz):
rear(0),front(0),tag(0),m(sz){
//建立一个最大具有m个元素的空队列。
Q=newType[m];
//创建队列空间
插入函数
template<
voidQueue<
Type>
:
EnQueue(Type&
item){assert(!
IsFull());
rear=(rear+1)%m;
Q[rear]=item;
tag=1;
//判队列是否不满,满则出错处理
//队尾位置进1,队尾指针指示实际队尾位置//进队列
//标志改1,表示队列不空
assert(Q!
=0);
//断言:
动态存储分配成功与否
//判断队列是否不空,空则出错处理
//队头位置进1,队头指针指示实际队头的前一位置//标志改0,表示栈不满//返回原队头元素的值
//返回队头元素的值
删除函数
TypeQueue<
DeQueue(){assert(!
IsEmpty());
front=(front+1)%m;
tag=0;
returnQ[front];
读取队头元素函数template<
GetFront(){assert(!
returnQ[(front+1)%m];
第4章串、数组和广义表
1.选择题
BBCABBBCBBABDCBC
2.综合应用题
(1)已知模式串t=‘abcaabbabcab'
写出用KMP法求得的每个字符对应的next和
nextval函数值。
模式串t的next和nextval值如下:
j
123456789101112
t串
abcaabbabcab
next[j]
011122312345
nextval[j]
011021301105
(3)数组A中,每个元素A[i,j]的长度均为32个二进位,行下标从-1到9,列下标从
1到11,从首地址S开始连续存放主存储器中,主存储器字长为16位。
求:
1存放该数组所需多少单元?
2存放数组第4列所有元素至少需多少单元?
3数组按行存放时,元素A[7,4]的起始地址是多少?
4数组按列存放时,元素A[4,7]的起始地址是多少?
每个元素32个二进制位,主存字长16位,故每个元素占2个字长,行下标可平移至1
到11。
(1)242
(2)22(3)S+182(4)s+142
⑷请将香蕉banana用工具H()—Head(),T()—Tail()从L中取出。
L=(apple,(orange,(strawberry,(banana)),peach),pear)
H(H(T(H(T(H(T(L)))))))
(5)写一个算法统计在输入字符串中各个不同字符出现的频度并将结果存入文件(字符串中的合法字符为A-Z这26个字母和0-9这10个数字)。
voidCount()
//统计输入字符串中数字字符和字母字符的个数。
{inti,num[36];
charch;
for(i=0;
36;
i++)num[i]=0;
//初始化
while((ch=getchar())!
=‘#'
)//‘#'
表示输入字符串结束。
if('
0'
<
=ch<
='
9'
){i=ch—48;
num[i]++;
//数字字符
elseif('
A<
Z){i=ch-65+10;
//字母字符
for(i=0;
10;
i++)//输出数字字符的个数
printf("
数字%d的个数=%d\n”,i,num[i]);
for(i=10;
i++)//求出字母字符的个数
字母字符%c的个数=%d\n”,i+55,num[i]);
}//算法结束。
第5章树和二叉树
1•选择题
ADDCACCBDCCCACC
2•应用题
2画出这棵二叉树的后序线索树。
3
将这棵二叉树转换成对应的树(或森林)
0.19,0.02,0.06,0.32,0.03,0.21,0.10。
1试为这8个字母设计赫夫曼编码。
2试设计另一种由二进制表示的等长编码方案。
3对于上述实例,比较两种方案的优缺点。
解:
方案1;
哈夫曼编码先将概率放大100倍,以方便构造哈夫曼树。
w={7,19,2,6,32,3,21,10},按哈夫曼规则:
【[(2,3),6],(7,10)】,……19,21,32
2(0.19+0.32+0.21)+4(0.07+0.06+0.10)+5(0.02+0.03)=1.44+0.92+0.25=2.61
方案2的WPL=3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3
结论:
哈夫曼编码优于等长二进制编码
3•算法设计题
以二叉链表作为二叉树的存储结构,编写以下算法:
(1)统计二叉树的叶结点个数。
intLeafNodeCount(BiTreeT)
{
if(T==NULL)
return0;
//如果是空树,则叶子结点个数为0
elseif(T->
lchild==NULL&
T->
rchild==NULL)
return1;
//判断该结点是否是叶子结点(左孩子右孩子都为空),若是则
返回1
else
returnLeafNodeCount(T->
lchild)+LeafNodeCount(T->
rchild);
(3)交换二叉树每个结点的左孩子和右孩子。
voidChangeLR(BiTree&
T)
BiTreetemp;
if(T->
return;
temp=T->
lchild;
T->
lchild=T->
rchild;
rchild=temp;
ChangeLR(T->
lchild);
CBBBCBABAADCCDDB
(1)已知如图6.27所示的有向图,请给出:
1
每个顶点的入度和出度;
2邻接矩阵;
3邻接表;
④逆邻接表。
i
5
fi
工
t
I
⑵罪讎阵
0000(T
1o0ioo
01000L
001011
100000
J1001ft.
1邻接矩阵;
2邻接表;
3最小生成树
43
45
35
55
9
59
7654
73
632
526
46
abcde
d
e
7
f
A
g
2
h
6
图6.28无
广度优先生战树
先生成树和广度优先生成树。
(4)有向网如图6.29所示,试用迪杰斯特拉算法求出从顶点a到其他各顶点间的最短
路径,完成表6.9。
图6.29邻接矩阵
V\终点\
i=1
i=2
i=3
i=4
i=5
i=6
b
15
(a,b)
⑻b)
c
(ac)
12
(a,d)
11
(a,c,f,d)
oo
10
(a,c,e)
(a,c,f)
co
16
(a,c,f,g)
(a,c,f,d,g)
S
终
点集
{a,c}
{a,c,f}
{a,c,f,e}
{a,c,f,e,d}
{a,c,f,e,d,g}
{a,c,f,e,d,g,b}
第7章查找
i选择题
CDCABCCCDCBCADA
(1)假定对有序表:
(3,4,5,乙24,30,42,54,63,72,87,95)进行折半查找,试回答下列问题:
1画出描述折半查找过程的判定树;
2若查找元素54,需依次与哪些元素比较?
3若查找元素90,需依次与哪些元素比较?
4假定每个元素的查找概率相等,求查找成功时的平均查找长度。
1先画出判定树如下(注:
mid=(1+12)/2=6):
2查找元素54,需依次与30,63,42,54元素比较;
3层共查找1+2X2+4X3=17
查找元素90,需依次与30,63,87,95元素比较;
4求ASL之前,需要统计每个元素的查找次数。
判定树的前
次;
但最后一层未满,不能用8X4,只能用5X4=20次,
所以ASL=1/12(17+20)=37/12~3.08
(2)在一棵空的二叉排序树中依次插入关键字序列为12,7,17,11,16,2,13,9,21,
4,请画出所得到的二叉排序树。
12\
八'
丿7、
2丿1丿621
4913
验算方法:
用中序遍历应得到排序结果:
2,4,7,9,11,12,13,16,17,21
(5)设哈希表的地址范围为0〜17,哈希函数为:
H(key)=key%16。
用线性探测法处理冲突,输入关键字序列:
(10,24,32,17,31,30,46,47,40,63,49),构造哈
希表,试回答下列问题:
1画出哈希表的示意图;
2若查找关键字63,需要依次与哪些关键字进行比较?
3若查找关键字60,需要依次与哪些关键字比较?
4假定每个关键字的查找概率相等,求查找成功时的平均查找长度。
①画表如下:
4
8
13
14
17
32
63
49
24
40
30
31
46
47
②查找63,首先要与H(63)=63%16=15号单元内容比较,即63vs31,no;
然后顺移,与46,47,32,17,63相比,一共比较了6次!
3查找60,首先要与H(60)=60%16=12号单元内容比较,但因为12号单元为空(应当有空标记),所以应当只比较这一次即可。
4对于黑色数据元素,各比较1次;
共6次;
对红色元素则各不相同,要统计移位的位数。
“63”需要6次,“49”需要3次,“40”需要
2次,“46”需要3次,“47”需要3次,
所以ASL=1/11(6+2+3X3+6)=23/11
(6)设有一组关键字(9,01,23,14,55,20,84,27),采用哈希函数:
H(key)=key%7,表长为10,用开放地址法的二次探测法处理冲突。
要求:
对该关键字序列构造哈希表,并计算查找成功的平均查找长度。
散列地址
关键字
01
23
84
27
20
比较次数
平均查找长度:
AS%c=(1+1+1+2+3+4+1+2)/8=15/8
以关键字27为例:
H(27)=27%7=6(冲突)H1=(6+1)%10=7(冲突)
H2=(6+22)%10=0(冲突)H3=(6+33)%10=5所以比较了4次。
第8章排序
CDBDCBCDBCBCCCA
(1)设待排序的关键字序列为{12,2,16,30,28,10,16*,20,6,18},试分别写出使用以下排序方法,每趟排序结束后关键字序列的状态。
1直接插入排序
2折半插入排序
3希尔排序(增量选取5,3,1)
4冒泡排序
5快速排序
6简单选择排序
7堆排序
8二路归并排序
①直接插入排序
[2
12]
28
16*
18
16]
30]
②
折半插入排序
排序过程同①
③
布尔排序(增量选取
5,
3,1)
28(增量选取
5)
3)
2C
)28
(增量选取1)
④
冒泡排序
[30]
[28
[20
[18
[16*
[16
[12
⑤
快速排序
[6
210]
16*201618]
[2]6
[10]
16*201618]
2610
20]28
[30]
26
18|
[20]2830
16*[16]1820
左子序列递归深度为1,右子序列递归深度为3⑥简单选择排序
18]
[30