数据结构习题有标准答案.docx
《数据结构习题有标准答案.docx》由会员分享,可在线阅读,更多相关《数据结构习题有标准答案.docx(30页珍藏版)》请在冰豆网上搜索。
![数据结构习题有标准答案.docx](https://file1.bdocx.com/fileroot1/2023-2/4/f7adb4b5-b74d-48fb-ac81-c0f8edf8683d/f7adb4b5-b74d-48fb-ac81-c0f8edf8683d1.gif)
数据结构习题有标准答案
第1章绪
1.1有下列几种二兀组表示的数据结构,
试画出它们分别对应的图形表示,
(1)
集合
并指出它们分别属于何种结构。
(1)A=(D,R),其中,D={a1,a?
.
a3,at},R={}
⑵
线性表
(2)B=(D,R),其中,D={a,b,
c
,d,e},R={(a,b),(b,c),
(c,d),
12
(d,e)}
(3)C=(D,R),其中,D={a,b,
c,d,e,f,g},R={(d,b),
(d,g),
(b,a),(b,c),(g,e),(e,f)}⑷K=(D,R),其中,D={1,
2,3,4,5,6},R={<1,2>
<2,
«c
4)
(0C)(
A
3>,<2,4>,<3,4>,<3,5>,<3,
6>,<4,5>,<4,6>}
树
⑶
丄⑷图
1.2设n为正整数,求下列各程序段中的下划线语句的执行次数。
(1)i=1;k=0
(2)for(inti=1;i<=n;i++)
解:
while(i<=n-1)
for(intj=1;j<=n;j++)
(1)n-1
{
{c[i][j]=0;
nn
n
:
仁n3
k+=10*i;
for(intk=1;k<=n;k++)
⑵
i++;
}
c[i][j]=c[i][j]+a[i][k]*b[k][j]
}
i=1jm
kT
(3)x=0;y=0;
nij
EEE
nin
仁送送j乏
i(i+1)一1卄
+£匸
1.n(n+1)(2n+1)+1.n(n+1)
for(inti=1;i<=n;i++)
⑶
i=tj=tk±izi
22耳
2tt
2622
for(intj=1;j<=i;j++)
n(n+1)(n*2)
for(intk=1;k<=j;k++)
6
x=x+v;
1.3指出下列个算法的功能,并求其时间复杂度。
(1)intsum1(intn)
{
intp=1,s=0;
for(inti=1;i<=n;i++){p*=i;s+=p;}returns;
}
⑵intsum2(intn)
{ints=0;
for(inti=1;i<=n;i++)
{intp=1;
for(intj=1;j<=i;j++)p*=j;s+=p;
}
解:
n
⑴'i!
T(n)=0(n)
n
(2)'i!
T(n)=O(n2)
iV
returns;
}
1.4算法设计
有3枚硬币,其中有天平,找出伪币?
以流程图表示算法。
上机练习题
要求:
给出问题分析、算法描述、源程序及运行截图,在线提交。
1.设a,b,c为3个整数,求其中位于中间值的整数。
第2章线性表
1.设计算法:
在顺序表中删除值为e的兀素,删除成功,返回1;否则,返回0。
intSqlist:
:
DeleteElem(Te)
{for(i=1;i<=length;i++)//按值顺序查找*i可从0开始
if(elem[i-1]==e)//找到,进行删除操作
{for(j=i;jElem[j-1]=elem[j];
length--;//表长减一
return1;〃删除成功,返回1
}
return0;//未找到,删除不成功,返回0
}
2.分析顺序表中兀素疋位算法intSqList:
:
Locate(Te)
的时间复杂度。
解:
设表长为n,等概率下,每个兀素被定位的概率为:
p-1/n
疋位成功第i个兀素,需比较i次
…、二1.1二.1n(n+1)n+1
f(n)_迟_Zi—•-
imnni二n22
3•对于有头结点的单链表,分别写出定位成功时,实现下列定位语句序列。
(1)定位到第i个结点ai;
p=head;j=0;
while(p&&jnext;j++;}
⑵定位到第i个结点的前驱a-1;
p=head;j=0;
while(p&&jnext;j++;}
(3)定位到尾结点;
p=head;
while(p->next)
p=p->next;
(4)定位到尾结点的前驱。
p=head;
while(p->next->next)p=p->next;
4•描述一下二个概念的区别:
头指针,头结点,首兀结点。
并给
头指针:
是一个指针变量,里面存储的是链表中首结点的地址,并以此来标识一个链表。
予图示。
头结点:
附加在第一个兀素结点之前的一个结点,头指针指向头结点。
首兀结点:
指链表中的第一个兀素结点。
头指针
头结点
首(元)结点尾(元)结点
aia2丨……Tna
5.对于无头结点单链表,给出删除第i个结点的算法描述。
template
TLinkList:
:
Delete(inti)
template
TLinkList:
:
Delete(inti){//在单链表上删除第i个数据元素
if(head==NULL)throw表空!
”;//空表,不能删elseif(i==1){//删除第1个兀素
p=Head;x=p->data;//保存被删兀素值
Head=p->next;
deletep;
}
else{//兀素疋位到第ai-1
p=Head;j=1;//疋位查找起始位置
while{p->next&&jp=p->next;j++;}
if(!
p->next||j>i-1);//定位失败
throw删除位置不合理;
else{//定位成功,进行结点删除
q=p->next;
x=p>data;
p->next=q->next;deleteq;
}
retrunx;//返回被删除兀素值
}//#
6.用教材定义的顺序表的基本操作实现下列操作:
template
intDeleteElem(SqListL,Te)
#includeSqList.h“templateintDeleteElem(SqListL,Te){//
i=L.LocateElem(e);//按值杳找
if(!
i)//未找到
return0;
else//找到
delete(i);//删除被找到的元素}
7.已知L是有表头结点的单链表,且P结点既不是首兀结点,
也不是尾结点,试写出实现下列功能的语句序列。
(1)在P结点后插入S结点;
(2)在P结点前插入S结点;
(3)在表首插入S结点;
(4)在表尾插入S结点.
【解】
(1)s->next=p->next;p->next=s;
⑵q=L;
while(q->next!
=p)q=q->next;
s->next=p或q->next;
q_>next=s;
(3)s->next=L->next;L->next=s;
⑶q=L;
while(q->next!
=NULL)q=q->next;
s->next=q->next;q->next=s;
上机练习题
要求:
给出问题分析、算法描述、源程序及运行截图,在线提交。
编程实现:
删除单链表中值为e的兀素。
第3章栈与队列
1.铁路进行列车调度时,常把站台设计成栈式结构的站台,如右图所示。
试问:
若进站的六辆列车顺序如上所述,那么
是否能够得到325641和154623的出站序列,如果不能,说明为什么不能;如果能,说明如何得到(即写出”进栈”或”出栈”的序列)。
2.简述以下算法的功能(栈的兀素类型为int)。
⑴statusalgo_1(SqStackS){
inti,n,A[255];
n=0;
while(!
S.StackEmpty()){n++;A[n]=S.Pop();}
for(i=1;i<=n;i++)S.Push(A[i]);
}
(2)statusalgo_2(SqStackS,inte){
SqStackT;
intd;
while(!
S.tackEmpty()){
d=S.Pop();
if(d!
=e)T.Push(d);}
while(!
T.StackEmpty()){
d=T.Pop();
T.Push(d);}
}
解:
(1)借助一个数组,将栈中的兀素逆置。
(2)借助栈T,将栈S中所有值为e的数据元素删除之。
3.编写一个算法,将一个非负的十进制整数N转换为B进制数,并输出转换后的结果。
当N=248D,B分别为8和16时,转换后的结果为多少?
#includestack.h”
intNumTrans(intN,intB){//十进制整数N转换为B进制数
stackS;//建立一个栈
while(N!
=0){//N非零
i=N%B;//从低到高,依次求得各位
N=N/B;
S.push(i);}//各位入栈while(!
S.StackEmpty()){//栈不空
{i=S.pop();
If(i>9)i=''10-i;
cout<}
}//#
4借且栈,设计算法:
假设一个算术表达式中包含“(、”“括号,
对一个合法的数学表达式来说,括号“(和“)应是相互匹配的。
若匹配,返回1;否则,返回0。
解:
以字符串存储表达式,也可以边输入边判断。
顺序扫描表达式,左括号,入栈;右括号,如果此时栈空,表示多右括号,不匹配;如果栈不空,出栈一个左括号。
扫描结束,如果栈空,表示括号匹配;否则,括号不匹配,多左括号。
intblank_match(char*exp){用字符串存表达式
SqStacks;//创建一个栈
char*p=exp;〃工作指针p指向表达式首while(*p!
==){//不是表达式结束符
switch(p){
case(:
〃左括号,入栈
s.push(ch);break;
case)//右括号
if(s.StackEmpty())return0;//栈空,不匹配,多右括号
else{s.Pop();break;}//左括号出栈
}//switch
p++;//取表达式下一个字符
}//while
if(!
s.StackEmpty())//表达式结束,栈不空
return0;//不匹配,多左括号else
return1;//匹配
}//#
5.简述栈和队列的逻辑特点,各举一个应用实例。
6.与出卜列中缀表达式的后缀表达式。
(1)A-B+C-D+
(1)-A+B-C+D
(2)AB+D*EFAD*+/+C+
(2)(A+B)*D+E/(F+A*D)+C
(3)AB&&EF!
||
⑶A&&B||!
(E>F)
7•计算后缀表达式:
45*32+-的值。
解:
15
8•将下列递推过程改写为递归过程。
解:
voidrecurision(intj)
voidrecursion(intn){
{if(j>1)
inti=n;
{cour<while(i>1){
recurision(j-1);}
cout<
}
}
9..将下列递归过程改写为非递归过程。
解:
voidtest(int&sum)
voidtest(int&sum){
{stackS;II借助一个栈
intx;
intx;
cin>>x;
cin>>x;
if(x==0)sum=0;
while(x){
else{
S.push(x);
test(sum);sum+=x;}
cin>>x;}
cout<sum=0;
}
cout<while(x=S.pop()){
sum+=x;cout<}II
10.简述以下算法的功能(栈和队列的兀素类型均为int)。
解:
禾U用栈,将队列中的兀素逆置
voidalgo(Queue&Q)
{
StackS;II创建一个栈
intd;
while(!
Q.QueueEmpty()){
d=DeQueue(Q);S.Push(d);}
while(!
S.StackEmpty()){
d=S.Pop();Q.EnQueue(d);}
}
12.假设以数组se[m]存放循环队列的兀素,冋时设变量rear和
front分别作为队首、队尾指针,且队首指针指向队首前一个位置,队尾指针指向队尾兀素处,初始时,rear==fornt==-1。
与出这样
设计的循环队列入队、出队的算法。
解:
米用教材队空与队满判别方法。
为了区分队空与队满条件,牺牲一个兀素空间。
即:
rear==front,为队空;rear==(front+1)%m,为队满。
template
voidEnQueue(TSe[],Te,intm){II入队
if(rear+1)%m=fornt){II队满,不能插入
throw队满,不能插入!
”
else{
rear=(rear+1)%m;II队尾指针后移
se[rear]=e;II兀素入队
return;
}
}II#
template
TDnQueue(TSe[],intm){II出队
if(rear==fornt)II队空,不能出队!
throw队空,不能出队!
”
else{
front=(front+1)%m;II指针后移,指向队首兀素e=se[front];II取队首兀素
returne;}
}//#
上机练习题
要求:
给出问题分析、算法描述、源程序及运行截图,在线提交。
1•借助栈,实现单链表上的逆置运算。
1•试问执行以下函数会产生怎样的输出结果?
voiddemonstrate()
{
StrAssign(s,'THISISABOOK');
StrRep(s,StrSub(s,3,7),'ESEARE');
StrAssign(t,StrConeat(s,'S'));
StrAssign(u,'XYXYXYXYXYXY');
StrAssign(v,StrSub(u,6,3));
StrAssign(w,W);
eout<<“'t=”<eout<<“v=”<eout<<“u=”<}//demonstrate
解:
t=THESEAREBOOKSv=YXY
w=XWXWXW
2.设字符串S=‘aabaabaabaae',P='aabaae'
1)给出S和P的next值和nextval值;
2)若S作主串,P作模式串,试给出KMP算法的匹配过程。
1)S的next与nextval值分别为012123456789和002002002009,p的next与nextval值分别为012123和002003
2)利用KMP算法的匹配过程:
第一趟匹配:
aabaabaabaae
aabaae(i=6,j=6)
第二趟匹配:
aabaabaabaae
(aa)baae
第三趟匹配:
aabaabaabaae
(成功)(aa)baae
3.算法设计串结构定义如下:
struetSString
{
char*data;//串首址
intlen;//串长
intStrSize;//存放数组的最大长度.
};
(1)编写一个函数,计算一个子串在一个字符串中出现的次数,如果不出现,则为0。
intstr_count(SStringS,SStringT)
解:
intstr_count(SStringS,SStringT){
inti,j,k,count=0;
for(i=0;S.data[i];i++){
for(j=i,k=0;(S.data[j]==T.data[k];j++,k++)if(k==T.len-1)
count++;
}
returncount;
}
⑵编写算法,从串s中删除所有和串t相同的子串。
解:
intSubString_Delete(SString&s,SStringt)
〃从串s中删除所有与t相同的子串,并返回删除次数
{
for(n=0,i=0;i<=s.len-t.len;i++)
{
for(j=0;jif(j>t.len)//找到了与t匹配的子串
{
for(k=i;k
s[k]=s[k+t.len];//左移删除
s.len-=t.len;
n++;II被删除次数增1}
}//forreturnn;
}//Delete_SubString
(2)编写一个函数,求串s和串t的一个最长公共子串。
voidmaxcomstr(SString*s,SString*t)
解:
voidmaxcomstr(SString*s,SString*t){
intindex=0,len1=0,i,j,k,len2;
i=0;//作为扫描s的指针
while(ij=0;//作为扫描t的指针
while(jif(s.data[i]==t.dataj){//序号为i,长度为Ien2的子串Ien2=1;//开始计数
for(k=1;s.data[i+k]==t.data[j+k]&&
s.data[i+k]!
=NULL;k++)
len2++;
if(len2>len1){//将较大长度者给index和Ien1
index=i;
len1=len2;
}
j+=len2;
}//if
elsej++;
}//while
cout<<最长公共子串:
for(i=0;icout<}//#
1.已知下列字符串
a='THIS',f='ASAMPLE',c='GOOD',d='NE',b=':
s=StrConcat(a,StrConcat(StrSub(f,2,7),StrConcat(b,StrSub(a,3,2)))),
t=StrRep(f,StrSub(f,3,6),c),
u=StrConcat(StrSub(c,3,1),d),g='IS',
v=StrConcat(s,StrConcat(b,StrConcat(t,StrConcat(b,u)))),
试问:
s,t,v,StrLength(s),StrIndex(v,g),StrIndex(u,g)各是什
么?
已知:
s='(XYZ)+*',t='(X+Z)*Y'。
试利用下列运算,将s转化
为t。
联接:
StrConeat(&S,T)
求子串:
(char*)StrSub(S,i,len)
置换:
StrRep(&S,T,R)
上机练习题
要求:
给出问题分析、算法描述、源程序及运行截图,在线提交。
串结构定义如下:
structSString
{
char*data;//串首址
intlen;//串长
intStrSize;//存放数组的最大长度.
};
求:
串S所含不冋字符的总数和每种字符的个数,不区分央文字
母的大小写。
第5章数组与压缩矩阵
1•假设有二维数组A6X3,每个兀素用相邻的6个字节存储,存储器按
字节编址。
已知A的起始存储位置(基地址)为1000,计算:
(1)数组A的体积(即存储量);
(2)数组A的最后一个兀素a57的第一个字节的地址;
(3)按行存储时,兀素a14的第一个字节的地址;
(4)按列存储时,兀素a47的第一个字节的地址。
解:
(1)6X8X6=288Byte
(2)1000+288-6=1282;
(3)1000+(1X8+4)X6=1072
(4)1000+(7X6+4)X6=127