数据结构大学期末复习重点.docx
《数据结构大学期末复习重点.docx》由会员分享,可在线阅读,更多相关《数据结构大学期末复习重点.docx(25页珍藏版)》请在冰豆网上搜索。
数据结构大学期末复习重点
一
一、名词解释:
数据类型和抽象数据类型,逻辑结构。
1、数据类型-高级语言中指数据的取值范围及其上可进行的操作的总称。
2、抽象数据类型-简称ADT,是指一个数学模型以及定义在该模型上的一组操作。
可用三元组表示(D,S,P),其中,D是数据对象,S是D上的关系集,P是对D的基本操作集。
如:
ADT抽象数据类型名{
数据对象:
<数据对象的定义>
数据关系:
<数据关系的定义>
基本操作:
<基本操作的定义>
}ADT抽象数据类型名
二、试依照三元组的抽象数据类型分别写出抽象数据类型有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。
ADTYls{
数据对象:
D={fz,fm|fz,fm∈N且fm≠0}
数据关系:
R={|fz为分子,fm为分母}
基本操作:
IntiYls(&z,z1,z2)
操作结果:
构造有理数z,其分子、分母分别被赋以z1、z2的值。
DestroyYls(&z)
操作结果:
有理数z被销毁。
Getfz(z,&fanzi)
初始条件:
有理数已存在。
操作结果:
用fanzi返回z的分子值。
Getfm(z,&fanmu)
初始条件:
有理数已存在。
操作结果:
用fanmu返回z的分母值。
Add(z1,z2,&sum)
初始条件:
有理数已存在。
操作结果:
用sum返回2个有理数之和。
Sub(z1,z2,&sub)
初始条件:
有理数已存在。
操作结果:
用sub返回2个有理数之差。
Mul(z1,z2,&mul)
初始条件:
有理数已存在。
操作结果:
用mul返回2个有理数之积。
Div(z1,z2,&div)
初始条件:
有理数已存在。
操作结果:
用div返回2个有理数之商。
}ADTYls
三、设N为正整数。
试确定下列名程序段中前置以记号@语句的频度:
(1)i=1;k=0;
do{
@k+=10*i;
i++;
}while(i<=n-1);
频度:
n=1时,为1;n≥2时,为n-1。
(2)i=1;k=0;
while(i<=n-1)
{
i++;
@k+=10*i;
}
频度:
n=1时,为1;n≥2时,为n-1。
(3)x=91;y=100;
while(y>0){
@if(x>100){x-=10;y--;}
elsex++;
}
频度:
1100
二
一、填空题
1、在顺序表中插入或删除一个元素,需要平均移动()元素,具体移动的元素个数与()有关。
表中的一半、表长和该元素在表中的位置
2、在单链表中设置头结点的作用是()。
插入和删除首元素时不必进行特殊的处理。
二、对以下单链表分别执行下列各程序段,并画出结果示意图。
1、T=P;
While(T!
=NULL){T—>data=T—>data*2;T=T—>next;}
答案在黑板上画。
2、T=P;
While(T—>next!
=NULL){T—>data=T—>data*2;T=T—>next;}
答案在黑板上画。
三、已知L是带表头结点的非空单链表,且P结点既不是第一个元素结点,也不是最后一个元素结点,请写出相应的语句序列完成下面的操作:
1、删除P结点的直接前驱结点的语句序列是:
Q=P;
P=L;
While(P->next->next!
=Q)P=P->next;
p->next=p->next->next;
2、删除最后一个元素结点的语句序列是:
Q=P;
While(Q->next->next!
=NULL){P=Q;Q=Q->next;}
P->next=p->next->next;
free(Q);
四、已知P结点是某双向链表的中间结点,请写出相应的语句序列完成下面的操作:
1、在P结点后插入S结点的语句序列是:
s->next=p->next;
p->next->prior=s;
p->next=s;
s->prior=p;
2、删除P结点的直接后继结点的语句序列是:
p->next->next->prior=p;
p->next=p->next->next;
五、设顺序表Va中的数据元素非递减有序。
写一算法将x插入到顺序表的适当位置上,以保持该表的有序性。
请参考《题集》P183。
三
一、简述栈和队列这两种数据类型的相同点和差异处?
略。
二、写出下列程序段的输出结果(栈的元素类型SElemType为char)。
voidmain()
{StackS;
Charx,y;
InitStack(S);
x=’c’;y=’k’;
Push(S,x);Push(S,’a’);Push(S,y);
Pop(S,x);Push(S,’t’);Push(S,x);
Pop(S,x);Push(S,’s’);
While(!
StackEmpty(S)){Pop(S,y);printf(y);}
printf(x);
}
stack
三、写出下列程序段的输出结果(队列中的元素类型QElemType为char)。
voidmain()
{QueueQ;InitQueue(Q);
Charx=’e’,y=’c’;
EnQueue(Q,’h’);EnQueue(Q,’r’);EnQueue(Q,y);
DeQueue(Q,x);EnQueue(Q,x);
DeQueue(Q,x);EnQueue(Q,’a’);
While(!
QueueEmpty(Q)){DeQueue(Q,y);printf(y);}
printf(x);
}
char
四、简述以下算法的功能(栈和队列的元素类型均为int)。
voidalgo3(Queue&Q)
{StackS;
intd;
InitStack(S);
While(!
QueueEmpty(Q)){DeQueue(Q,d);Push(S,d);}
While(!
StackEmpty(S)){Pop(S,d);EnQueue(Q,d);}
}
利用“栈”作辅助,将“队列”中的数据元素进行逆置。
四
一、(习题集4.4)已知下列字符串
a=’THIS’,f=’ASAMPLE’,C=’GOOD’,D=’NE’,b=’’,
s=Concat(a,Concat(SubString(f,2,7),Concat(b,SubString(a,3,2)))),
t=Replace(f,SubString(f,3,6),c),
u=Concat(SubString(c,3,1),d),g=’IS’,
v=Concat(s,Concat(b,Concat(t,Concat(b,u)))),
试问:
s,t,v,StrLength(s),Index(v,g),Index(u,g)各是什么?
s=’THISSAMPLEIS’
t=’AGOOD’
u=’ONE’
v=’THISSAMPLEISAGOODONE’
StrLength(s)=14Index(v,g)=3Index(u,g)=0
二|、(习题集4.6)已知:
s=’(XYZ)+*’,t=’(X+Z)*Y’,试利用联接,求子串和置换等基本运算,将s转化为t。
substring(s1,s,3,1);//返回s1=’Y’
substring(s2,s,6,1);//返回s2=’+’
replace(s,s1,s2);//返回s=’(X+Z)+*’
substring(s3,s,7,1);//返回s3=’*’
substring(s4,s,1,5);//返回s4=’(X+Z)’
concat(t,s4,s3);//返回t=’(X+Z)*’
concat(t,t,s1);//返回t=’(X+Z)*Y’
三、编写算法实现串的基本操作StrInsert(&S,pos,T)(S,T用定长顺序存储表示)。
StatusStrInsert(SString&S,intpos,SStringT){
if(pos<1||pos>S[0]+1)returnERROR;
if(S[0]+T[0]<=MAXSTRLEN){
for(i=S[0];i>=pos;--i)
S[i+T[0]]=S[i];
S[pos...pos+T[0]-1]=T[1...T[0]];
S[0]=S[0]+T[0];
uncut=TRUE;
}
elseif(pos+T[0]-1for(i=MAXSTRLEN-T[0];i>=pos;--i)
S[i+T[0]]=S[i];
S[pos...pos+T[0]-1]=T[1...T[0]];
S[0]=MAXSTRLEN;
uncut=FALSE;
}
else
{
S[pos...MAXSTRLEN]=T[1...MAXSTRLEN-pos+1];
S[0]=MAXSTRLEN;
uncut=FALSE;
}
returnuncut;
}
五
1、设数组B[1..3,1..5]中的任一元素均占4个单元,从首地址SA=2001开始把数组B按列优先存储,则元素B[2,4]的地址为2041。
2、设数组B[0..4,0..5]中的任一元素均占3个单元,从首地址SA=20开始把数组B按行优先存储,则元素B[4,4]的地址为104。
3、下列广义表操作的结果为:
GetHead(GetTail((a,b),(c,d)))(c,d)。
4、利用GetHead和GetTail操作把下列广义表中的原子banana分离出来
L1=((apple,pear),(banana,orange))
GetHead(GetHead(GetTail(L)))。
5、画出下列每个广义表的带表头附加结点的链接存储结构图并分别计算出它们的长度和深度。
(1)A=(())长度是1,深度是2
(2)B=(a,b,c)长度是3,深度是1
(3)C=(a,(b,(c)))长度是2,深度是3
(4)E=(a,(b,(c,d)),(e))长度是3,深度是3
6、假设稀疏矩阵A和B均以三元组顺序表作为存储结构。
试写出矩阵相加的算法,另设三元组表C存放结果矩阵。
TSMatrixAddTriTuple(TSMatrixA,TSMatrixB)
{TSMatrixC;/*三元组表表示的稀疏矩阵A,B相加;*/
intk=0,l=0,t=0;
inttemp;
C.mu=A.mu;
C.nu=A.nu;
while(k{if((A.data[k].i==B.data[l].i)&&(A.data[k].j==B.data[l].j))/*A,B稀疏矩阵两个非零元的行标和列标都相同*/
{temp=A.data[k].e+B.data[l].e;
if(temp)/*A,B稀疏矩阵两个非零元相加不为0*/
{C.data[t].i=A.data[k].i;
C.data[t].j=A.data[k].j;
C.data[t].e=temp;
k++;l++;t++;
}
else{k++;l++;}
}
elseif((A.data[k].i==B.data[l].i)&&(A.data[k].j{C.data[t].i=A.data[k].i;
C.data[t].j=A.data[k].j;
C.data[t].e=A.data[k].e;
k++;t++;
}
else/*if((A.data[k].i==B.data[l].i)&&(A.data[k].j>B.data[l].j)||(A.data[k].i>B.data[l].i))*/
{C.data[t].i=B.data[l].i;
C.data[t].j=B.data[l].j;
C.data[t].e=B.data[l].e;
l++;t++;
}
}
while(k{C.data[t].i=A.data[k].i;
C.data[t].j=A.data[k].j;
C.data[t].e=A.data[k].e;
k++;t++;
}
while(l{C.data[t].i=B.data[l].i;
C.data[t].j=B.data[l].j;
C.data[t].e=B.data[l].e;
l++;t++;
}
C.tu=t;
returnC;
}
六
1、二叉数第J层上有大于0且小于或等于2j-1个结点。
(性质1)
2、假定一棵树的广义表表示为A(B(C,D(E,F,G),H(I,J))),则度为3、2、1、0的结点数分别为__2____、_1_____、___1___和___6___个。
3、在一棵二叉树中,假定双分支结点数为5个,单分支结点数为6个,则叶子结点数为___6_____个。
(根据性质3)
4、对于一棵有135个结点的完全二叉树,若一个结点的编号为65,则它的左孩子结点的编号为___130_____,右孩子结点的编号为__131______,双亲结点的编号为___32_____。
(性质5)
5、在一棵二叉树中,第5层上的结点数最多为__16____。
(性质1)
6、假定一棵二叉树的结点数为18,则它的最小深度为___5_____,最大深度为____18____。
(最大深度的是单支树,其深度为n;最小深度即为完全k叉树,根据性质4可得)
7、一棵二叉树的广义表表示为a(b(c,d),e(f(,g))),它含有双亲结点___4___个,单分支结点___1___个,叶子结点___4___个。
8、对于一棵具有n个结点的二叉树,对应二叉链表中指针总数为____2n____个,其中___n-1_____个用于指向孩子结点,___n+1_____个指针空闲着。
9、设根结点的层数为1,定义树的高度为树中层数最大的结点的层数。
则高度为K二叉树具有的结点数目,最少为K最多为2k-1。
10、一棵完全二叉树有110个结点,度为1的结点有1个,叶子结点有55个。
11、已知二叉树的先序、中序和后序序列分别如下,但其中有一些已模糊不清,请填上已缺的数据,并画出该二叉树
先序序列:
JGAHBICDKEF
中序序列:
AGBHCIDJEKF
后序序列:
ABCDIHGEFKJ。
12、假设一颗二叉树的中序序列为DCBGEAHFIJK和后序序列为DCEGBFHKJIA。
请画出该树,同时先序前驱线索化。
先序序列为ABCDGEIHFJK
七
1、画出和下列已知序列对应的森林F:
森林的先序次序访问序列为:
ABCDEFGHIJKL;
森林的中序次序访问序列为:
CBEFDGAJIKLH;
解法:
根据先序遍历森林和中序遍历森林的序列画出对应的由森林转换而成的二叉树,然后再将该二叉树转换成对应的森林即得。
该森林对应的二叉树为:
该二叉树对应的森林为:
2、电文中的字符及其概率如下:
x a b c d e
p(x) 0.5 0.25 0.125 0.0625 0.0625
试画出下列字符的Huffman赫夫曼树,求其Huffman编码,平均码长。
1
0
1
0
1
0
1
0
字符
a
b
c
d
e
Huffman编码
0
10
110
1110
1111
WPL=0.5*1+0.25*2+0.125*3+0.0625*4+0.0625*4=1.875
3、分别画出具有3个结点的树和3个结点的二叉树的所有不同形态。
含三个结点的树只有两种形态:
含3个结点的二叉树可能有下列5种形态:
4、找出满足下列条件的二叉树:
①先序和中序遍历时得到的结点访问序列相同。
空树或除叶子结点外,其余结点只有右子树,没有左子树的二叉树
②后序和中序遍历时得到的结点访问序列相同。
空树或除叶子结点外,其余结点只有左子树,没有右子树
③先序和后序遍历时得到的结点访问序列相同。
空树或只有根结点的树
八
1、对于下图所示的有向图,列出所有可能的拓扑有序序列。
1→2→3→4→5→6
或1→3→4→2→5→6
或1→3→2→4→5→6
2、写出上面有向图的逆邻接表和邻接矩阵。
邻接矩阵为:
123456
1
2
3
4
5
6
3、把教科书7.1节中7.3(a)所示的无向图,画出其广度优先生成森林。
4、列出下面无向图的深度优先和广度优先遍历所得顶点序列,同时给出相应的深度优先生成树。
(从顶点1开始,当邻接顶点有多个时选编号小的顶点)
深度优先遍历:
1→2→5→4→3→6
广度优先遍历:
1→2→3→4→6→5
深度优先生成树:
5、分别用普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法构造下面无向网的最小生成树方法
(写出每一步过程)
普里姆(Prim)算法:
(1)顶点1加入生成树
(2)因为与1相邻的边权值最小为2,所以取权值最小的边(1,6)
2
(3)因为与1相邻的边中(1,3)的权值小于(6,5)的权值,所以继续取边(1,3)
4
2
(4)因为剩余的与1相邻的边的权值都大于(6,5)的权值,所以取边(6,5)
4
2
5
(5)因为与5相邻的边(5,2)的权值最小,所以取边(5,2)
4
1
2
5
(6)因为与5的相邻的边(5,4)的权值最小,所以取边(5,4)
4
1
2
3
5
克鲁斯卡尔(Kruskal)算法:
(1)构造只含6个顶点的森林
(2)选择权值最小的边(2,5)加入森林
1
(3)选择剩下的权值最小的边(1,2)加入森林
1
2
(3)选择剩下的权值最小的边(4,5)加入森林
1
2
3
(4)选择剩下的权值最小的边(1,3)加入森林
4
1
2
3
(5)选择剩下的权值最小的边(5,6)加入森林
4
1
2
3
5
九
1、画出对长度为10的有序表进行折半查找的判定树,并求其等概率时查找成功的平均查找长度。
等概率时查找成功的平均查找长度为:
ASL=
(1*1+2*2+3*4+4*3)=2.9
2、已知一个有序表为(11,22,33,44,55,66,77,88,99),则顺序查找元素55需要比较5次。
3、折半查找不成功时和给定值进行比较的关键字个数最多为5次(设表长17)。
(P220折半查找不成功时和给定值进行比较的关键字个数最多也不超过
)
4、用线性探测法建立哈希表,哈希函数为H(key)=keymod11,哈希表长度为10,现有一组关键字(61,18,30,72,13,24),请画出相应哈希表。
0123456789
13
24
61
18
30
72
(1)H(61)=61mod11=6不冲突
(2)H(18)=18mod11=7不冲突
(3)H(30)=30mod11=8不冲突
(4)H(72)=72mod11=6冲突
H1=(6+1)mod10=7冲突
H2=(6+2)mod10=8冲突
H3=(6+3)mod10=9不冲突
(5)H(13)=13mod11=2不冲突
(6)H(24)=24mod11=2冲突
H1=(2+1)mod10=3不冲突
5、用链地址法建立哈希表,哈希函数为H(key)=keymod11,现有一组关键字(61,18,72,13,24,12,11),请画出哈希表。
(1)H(61)=61mod11=6
(2)H(18)=18mod11=7
(3)H(72)=72mod11=6
(4)H(13)=13mod11=2
(5)H(24)=24mod11=2
(6)H(12)=12mod11=1
(7)H(11)=11mod11=0
0
1
2
3
4
5
6
7
8
9
10
∧
∧
∧
∧
∧
∧
十
1、在直接插入排序中,若初始序列为“逆序”序列,则须进行比较的次数为54,记录移动的次数为63。
设表长为10。
若待排序记录按关键字从大到小排列(逆序)
关键字比较次数:
记录移动次数:
2、关键字(49,38,65,97,76,13,27)取d=3用希尔排序后,得到的排序结果为(27,38,13,49,76,65,97),其中进行了4次直接插入排序。
3、关键字(49,38,65,97,76,13,27)完成一趟快速排序后得到的排序结果为(27,38,13,49,76,97,65)。
4、关键字(49,38,65,97,76,13,27)完成三趟简单选择排序后得到的排序结果为(13,27,38,97,76,49,65)。
5、关键字(49,38,65,97,76,13,27)对其进行归并排序的过程中,第二趟归并后的结果为_(38,49,65,97,13,27,76)__。
6、关键字(49,38,65,97,76,13,27)利用堆排序方法建立的初始堆为_(13,38,27,97,76,65,49)_。
7、每次从无序表中取出一个元素,把它插入到有序表中的适当位置,此种排序方法叫做_直接插入_排序;每次从无序表中挑选出一个最小或最大元素,把它交换到有序表的一端,此种排序方法叫做_简单选择_排序。
8、在起泡排序中,当待排序列是正序时,总的比较次数是_9__,记录移动次数是_0__。
设表长为10。
最好情况(正序)
比较次数:
n-1
移动次数:
0
9、起泡排序的时间复杂度是_O(n2)_,直接插入排序的时间复杂度是_O(n2)_。