数据结构15章习题参考答案.docx
《数据结构15章习题参考答案.docx》由会员分享,可在线阅读,更多相关《数据结构15章习题参考答案.docx(19页珍藏版)》请在冰豆网上搜索。
![数据结构15章习题参考答案.docx](https://file1.bdocx.com/fileroot1/2023-1/23/feb81535-edc9-435c-b07a-1531afae16e9/feb81535-edc9-435c-b07a-1531afae16e91.gif)
数据结构15章习题参考答案
第1章绪论
一、填空题
01、【操作对象】【关系和运算】
02、【数据元素】【关系】
03、【逻辑结构】【存储结构】【运算】
04、【线性结构】【非线性结构】
05、【一对一】【一对多】【多对多】
06、【没有】【没有】
07、【前驱】【1】【后续】【任意多个】
08、【任意多个】
09、【顺序】【链式】【索引】【散列】
10、【集合】【线性结构】【树形结构】【图状结构】
11、【插入】【删除】【修改】【查找】【排序】
12、【时间】【空间】
13、【时间复杂度】【空间复杂度】
14、【映射】
15、【有穷性】【确定性】【可行性】
16、【n+1】【n】【n(n+3)/2】【n(n+1)/2】
17、【n(n+1)(n+2)/6】【O(n3)】
18、【O(
)】
19、【O(n
)】
20、【O(
)】
21、【(n+3)(n-2)/2】
22、【n(n-1)/2】
二、判断题
01-05、×××√×06-10、×√×××11-12、√×
三、单项选择题
B01BD02A03C04C05
A06C07B08A09C10
B11A12C13D14A15
C16
四、分析下面各程序段的时间复杂度
01、O(
)
02、O(
)
03、答:
O(
)
04、答:
O(
)
五、设有数据逻辑结构S=(D,R),试按各小题所给条件画出这些逻辑结构的图示,并确定相对于关系R,哪些结点是开始结点,哪些结点是终端结点?
01、此图为线性结构d1→d2→d3→d4
d1—无直接前驱,是首结点
d4—无直接后继是尾结点
02、此图为树形结构
d1—无直接前驱,是根结点
d2,d5,d7,d9—无直接后继是叶子结点
03、此图为图形结构
d1,d2—无直接前驱,是开始结点
d6,d7—无直接后继是终端结点
六、简述题
01、什么是数据结构?
答:
数据结构是一门研究非数值计算的程序设计问题中计算机的操作对象以及它们之间的关系和运算等的学科。
02、顺序存储结构和链式存储结构的特点是什么?
答:
顺序存储结构是指数据元素的逻辑存储顺序和计算机中的物理存储顺序一致,即数据占用一段连续的存储单元,该存储结构便于实现在查找数据元素时的地址定位,但缺点是在插入和删除操作时需要移动大量的数据元素。
链式存储结构是指数据元素在计算机中占用不连续的存储单元,通过指针指向表示其先后顺序,该存储结构缺点是在查找数据元素时要通过指针的链接关系才能找到所要的数据元素,优点在于插入和删除操作时,不需要移动大量数据元素,只需要改变其指向关系即可。
第2章线性表
一、填空题
01、【顺序】
02、【(n-1)/2】
03、【n/2】【表长】【该元素在表中的位置】
04、【有限】【一对一】
05、【n-i+1】
06、【n-i】
07、【O
(1)】【随机存取】
08、【必定相邻】【未必相邻】
09、【其直接前驱结点的链域值】
10、【前驱结点的地址】【O(n)】
11、【py->next=px->next;px->next=py;】
12、【在第一个元素之前插入元素和删除第一个结点】
13、【O
(1)】【O(n)】
14、【f->next=p->next;f->prior=p;p->next->prior=f;p->next=f;】
15、【p->prior】【s->prior->next】
16、【指针】
17、【4】【2】
18、【从任一结点出发都可访问到链表中每一个元素】
19、【u=p->next;p->next=u->next;free(u);】
20、【L->next->next==L】
21、【p->next!
=null】
22、【L->next==L&&L->prior==L】
23、【s->next=p->next;p->next=s;】
二、判断题
01-05、×××××
06-10、×××××
11-15、×√√××
16-20、××××√
三、单项选择题
C01B02A03B04A05A06D07B08C09D10
D11A12B13C14C15A16A17B18D19B20
C21A22C23A24B25C26C27C28B29B30
A31D32A33
四、简述题
1、按课本定义,写出顺序表的存储结构。
typedefstructnode
{ElemType*elem;
intlength;}SqList
2、按课笨定义,写出链表的存储结构。
typedefstructNode
{ElemTypedata;
structNode*next;}Node,*LinkList;
五、代码填空题
01、【s->data=e】【s->next=p->next】【p->next=s】
02、【q=p->next】【p->next=q->next】【free(q)】
03、【L->next=NULL】【p->next=L->next】【L->next=p】
04、【q->next=p】【q=p】【p->next=NULL】
05、【L==NULL或!
L】【p=p->next】
06、【p->next】【r】【q】
07、【q=L】【q=p】【p=p->next】
六、算法设计题
01、在顺序表中求值为X的元素个数。
(不允许调用ADT预定义操作)
intcount(SqListL,ElemTypex)
{if(!
L.Elem)returnERROR;
n=0;
for(i=0;iif(L.elem[i]==x)
n++;
returnn;
}
02、在有头结点的链表中删除重复元素,要求保留首次出现的元素。
(不允许调用ADT预定义操作)
voidDeleteRepElem(LinkList*L)
{LinkListr,p,q;
r=(*L)->next;
while(r!
=NULL)
{q=r;p=r->next;
while(p!
=NULL)
{if(p->data==r->data)
{q->next=p->next;free(p);p=q->next;}
else
{q=p;p=p->next;}
}
r=r->next;
}
}
03、插入法建立有序链表。
(不允许调用ADT预定义操作)
voidCreateList_3(LinkList&L,intn)
{L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
for(i=1;i<=n;i++)
{new=(LinkList)malloc(sizeof(LNode));
scanf(&new->data);
q=L;p=L->next;
while(p!
=NULL&&p->datadata)
{q=p;p=p->next;}
new->next=p;q->next=new;
}
}
04、判断链表是否为递增顺序。
(不允许调用ADT预定义操作)
intIncrease(LinkListL)
{pre=L->next;
if(pre<>NULL)
while(pre->next<>NULL)
{p=pre->next;
if(p->data>pre->data)
pre=p
else
returnFALSE;
}
returnTRUE;
}
05、已知两个线性表A、B,且其数据元素递增,要求按课本定义的ADT,设计算法求出A、B的交集C,并同样以递增顺序存储。
voidUnionList(ListLa,ListLb,List&Lc)
{InitList(Lc);
i=1;j=1;k=1;
La_len=ListLength(La);Lb_len=ListLength(Lb);
while((i<=La_len)&&(j<=Lb_len))
{
GetElem(La,i,ai);GetElem(Lb,j,bj);
if(aii++;
elseif(ai>bj)
j++;
else
{ListInsert(Lc,k,ai);i++;j++;k++;}
}
}
06、已知两从此集合A、B,且每个集合中没有重复元素,要求按课本定义的ADT,设计算法分别求出集合A和集合B的并集、交集和差集。
/*******G
(1).集合运算:
并集******/
voidUnion(SqListLa,SqListLb,SqList*Lc)
{inti,j,alen,blen;ElemTypee;
InitList(Lc);
alen=ListLength(La);blen=ListLength(Lb);
j=1;
for(i=1;i<=alen;i++)
{GetElem(La,i,&e);
ListInsert(Lc,j++,e);}
for(i=1;i<=blen;i++)
{GetElem(Lb,i,&e);
if(!
LocateElem(La,e))
ListInsert(Lc,j++,e);}
}
/*******G
(2).集合运算:
交集******/
voidInterSection(SqListLa,SqListLb,SqList*Lc)
{inti,j,alen;ElemTypee;
InitList(Lc);
alen=ListLength(La);
j=1;
for(i=1;i<=alen;i++)
{GetElem(La,i,&e);
if(LocateElem(Lb,e))
ListInsert(Lc,j++,e);}
}
/*******G(3).集合运算:
差集******/
voidDiffSet(SqListLa,SqListLb,SqList*Lc)
{inti,j,alen;ElemTypee;
InitList(Lc);
alen=ListLength(La);
j=1;
for(i=1;i<=alen;i++)
{GetElem(La,i,&e);
if(!
LocateElem(Lb,e))
ListInsert(Lc,j++,e);}
}
07、已建立约瑟环的单向循环链表,并在结点中存储10个整数,要求调用课本定义的ADT操作,设计算法反复按1-3报数,报到3删除结点并显示该结点的值。
voidJoseffer1(intn)
{inti,len;ElemTypee;LinkListL;
InitList(&L);
CreateJoseffer(&L,n);
i=1;
while(!
ListEmpty(L))
{len=ListLength(L);
i++;if(i>len)i%=len;
i++;if(i>len)i%=len;
ListDelete(&L,i,&e);printf("%3d",e);
}
}
08、已建立带头结点约瑟环的单向循环链表,并在结点中存储10个整数,设计算法反复按1-3报数,报到3删除结点并显示该结点的值。
(不允许调用ADT预定义操作)
voidJoseffer2(intn)
{LinkListL,p,q;
InitList(&L);
CreateJoseffer(&L,n);
q=L;p=L->next;
while(L->next!
=L)
{q=p;p=p->next;if(p==L){q=p;p=p->next;}//p指向头指点
q=p;p=p->next;if(p==L){q=p;p=p->next;}
printf("%3d",p->data);
{q->next=p->next;
free(p);
p=q->next;
if(p==L){q=p;p=p->next;}
}
}
}
第3章栈和队列
一、填空题
01、【线性】【栈顶】【队尾】【队首】
02、【栈顶】【栈底】
03、【操作受限】【后进先出】【先进先出】
04、【栈】
05、【队列】
06、【前一个】
07、【n-1】
08、【SXSSXSXX】
09、【4】
10、【O
(1)】
11、【5】
12、【3、1、2】
13、【2、3】【100C】
14、【满】【空】
15、【链式】
16、【SXSSXSXX】
17、【data[++top]=x】
18、【假溢出时大量移动数据元素】
19、【(M+1)%N】
20、【先进先出】
21、【牺牲一个存储单元或设置标记】
22、【(r+1)%M=f】
23、【栈】
24、【(r-f+m)%m】
二、判断题
01-05、√×××√06-10、×××√×
11-15、×√√×√16-20、√√×××
21-22、√×
三、选择题
B01B02B03A04B05C06C07B08B09D10
C11A12B13C14C15D16C17D18D19C20
D21C22D23C24D25C26A27D28D29C30
A31C32C33B34
四、简述题
01、按书本定义,分别写出栈的顺序存储结构和链式存储结构。
顺序栈:
typedefstructSqStack
{ElemType*base;
ElemType*top;}SqStack;
链栈:
typedefstructNode
{ElemTypedata;
structNode*next;}Node,*LinkStack;
02、按书本定义,分别写出队列的顺序存储结构和链式存储结构。
链队列:
typedefstructNode
{ElemTypedata;
structNode*next;
}QNode,*QueuePtr;
typedefstruct
{QueuePtrfront;
QueuePtrrear;
}LinkQueue;
顺序列队(循环队列):
typedefstruct
{ElemType*base;
intfront;
intrear;
}SqQueue;
03、顺序队列的“假溢出”是怎样产生的?
如何知道循环队列是空还是满?
答:
一般的一维数组队列的尾指针已经到了数组的上界,不能再有入队操作,但其实数组中还有空位置,这就叫“假溢出”。
采用循环队列是解决假溢出的途径。
另外,解决队满队空的办法有三:
设置一个布尔变量以区别队满还是队空;
浪费一个元素的空间,用于区别队满还是队空。
使用一个计数器记录队列中元素个数(即队列长度)。
我们常采用方法二,即队头指针、队尾指针中有一个指向实元素,而另一个指向空闲元素。
判断循环队列队空标志是:
front=rear
队满标志是:
front=(rear+1)%N
五、阅读理解
01、输出为“stack”。
02、输出为“char”。
03、该算法的功能是:
利用堆栈做辅助,将队列中的数据元素进行逆置。
04、程序段的功能是将一栈中的元素按反序重新排列,也就是原来在栈顶的元素放到栈底,栈底的元素放到栈顶。
此栈中元素个数限制在64个以内。
05、程序段的功能是利用tmp栈将一个非空栈的所有元素按原样复制到另一个栈中去。
06、程序段的功能是将一个非空栈中值等于m的元素全部删去。
六、代码填空
01、
(1)【S.top++】
(2)【S.top--】
02、
(1)【Q.rear->next=p】【Q.rear=p】
(2)【Q.front==Q.rear】【Q.rear==p】
03、【S.top=S.base】
04、【push(S,N%8)】【pop(S,e)】
七、算法设计
01、请写出链栈的“入栈”和“出栈”操作。
(1)链栈入栈
voidPush(LinkStack*top,ElemTypee)
{LinkStacknew;
new=(LinkStack)malloc(sizeof(SNode));
new->data=e;
new->next=*top;*top=new;}
(2)链栈出栈
voidPop(LinkStack*top,ElemType*e)
{LinkStackp;
if(*top!
=NULL)
{*e=(*top)->data;
p=*top;(*top)=p->next;
free(p);}
}
02、请写出循环队列的“入队列”和“出队列”操作。
(1)循环队列入队列
StatusEnQueue(SqQueue&Q,ElemTypee)
{if((Q.rear+1)%MaxSize==Q.front)returnError;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MaxSize;
returnOK;}
(2)循环队列出队列
StatusDeQueue(SqQueue&Q,ElemType&e)
{if(Q.front==Q.rear)returnError;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MaxSize;
returnOK;}
03、删除数字栈中元素值为奇数的栈元素。
voidDelOddnumber(Stack&S)
{StackT;ElemTypee;
while(!
StackEmpty(S))
{Pop(S,&e);
if(e%2==0)Push(T,e);
}
while(!
StackEmpty(T))
{Pop(T,&e);Push(S,e);}
}
04、若把栈s1看成一个队列(队头在栈顶,队尾在栈底),请利用栈的运算,并借助于辅助栈s2,实现队列的“出列”运算。
voidDeQueue(Stack&s1,Stacks2,intx)/*本函数功能:
删除一个元素*/
{inty;
ClearStack(s2);
while(!
StackEmpty(s1))
{Pop(s1,y);Push(s2,y);}
Pop(s2,x);
while(!
StackEmpty(s2))
{Pop(s2,y);Push(s1,y);}
}
05、利用栈和队列的操作,完成对字符序列是否为“回文”的判断。
intStrTest()
{chara,b,c;
SqStackS;LinkQueueQ;
InitStack(&S);InitQueue(&Q);
printf("\ninputstring:
");
while((c=getchar())!
='\n')
{Push(&S,c);EnQueue(&Q,c);}
while(!
StackEmpty(S))
{Pop(&S,&a);DeQueue(&Q,&b);
if(a!
=b)return0;}
return1;}
06、下面算法的功能是利用队列求解约瑟夫环问题,请填空。
voidJoseffer(intn)
{LinkQueueQ;inti;ElemTypex;
InitQueue(&Q);
for(i=1;i<=n;i++)
EnQueue(&Q,i);
while(!
QueueEmpty(Q))
{for(i=1;i<=3;i++)
{DeQueue(&Q,&x);
if(i!
=3)
EnQueue(&Q,x);
else
printf("%5d",x);}
}
}
07、复习课本中关于“数制转换”、“括号匹配”、“行编辑”、“表达式求值”的算法。
第4、5章串和数组
一、填空题
01、【空串】【一个或多个空格(仅由空格符)】
02、【两个串的长度相等且对应位置的字符相同】
03、【20】【3】
04、【模式匹配】【主串】【子串】
05、【6】
06、【(n-m+1)*m】
07、【288B】【1282】【(8+4)×6+1000=1072】【(6×7+4)×6+1000)=1276】
08、【8950】
09、【行下标】【列下标】【元素值】
10、【(d1-c1+1)*(d2-c2+1)】
11、【Loc(A[0][0])+(n*i+j)*k】
12、【42】
13、【20】
14、【字符】
15、【任意个连续的字符组成的子序列】
16、【O(m+n)】
17、【模式匹配】
18、【数据元素都是字符】
19、【'xyxyxywwy'】
20、【j++】【i>=j】
21、【定长顺序】【堆分配】
22、【1100】
23、【9572】【1228】
24、【1164】
25、【1】【3】
26、【i(i-1)/2+j】
27、【n(n+1)/2】【i(i+1)/2】【i(i-1)/2+j】【j(j-1)/2+i】
28、【1038】。
29、【33】
30、【93】
二、判断题
01-05、×××√√06-08、×××
三、选择题
C01C02B03B04D05
D06B07D08C09B10
A11B12B13B14C15
B16B17B18B19B20B21A22C23
四、综合题
01、
①Replace(s,"STUDENT",q)=’IAMAWORKER’
②因为SubString(s,6,2)="A";SubString(s,7,8)="STUDENT"
Concat(t,SubString(s,7,8))="GOODSTUDENT"
所以Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))="AGOODSTUDENT"
02、ije
132
213
331
345
03、
五、算法填空题
01、【SubString(&sub,S,i,m)】【returni】
02、【i<=S[0]&&i<=T[0]】【S[i]-T[i