数据结构习题有答案Word文档格式.docx
《数据结构习题有答案Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构习题有答案Word文档格式.docx(28页珍藏版)》请在冰豆网上搜索。
解:
(1)n-1
n
(2)
1n3
i1
j1
k1
i
j
ni(i
1)
1n
i2
(3)i1
1k
2
2i
2i1
n(n1)(n2)
6
5
4
1n(n1)(2n1)1n(n1)
2622
1.3指出下列个算法的功能,并求其时间复杂度。
(1)intsum1(intn)
(2)intsum2(intn)
{{ints=0;
intp=1,s=0;
for(inti=1;
i<
i++){intp=1;
{p*=i;
s+=p;
}for(intj=1;
j++)p*=j;
returns;
1.4算法设计
有3枚硬币,其中有1枚是假的,伪币与真币重量略有不同。
如何借用一架天平,找出伪币?
以流程图表示算法。
上机练习题
要求:
给出问题分析、算法描述、源程序及运行截图,在线提交。
1.设a,b,c为3个整数,求其中位于中间值的整数。
(1)
i!
T(n)=O(n)
T(n)=O(n2)
开始
是
A=B?
C是伪币
否
A=C?
B是伪币
A是伪币
结束
第2章线性表
1.设计算法:
在顺序表中删除值为
e的元素,删除成功,返回1;
intSqlist<
T>
:
DeleteElem(Te)
否则,返回0。
{for(i=1;
=length;
i++)//
按值顺序查找
*i可从0开始
if(elem[i-1]==e)
//
找到,进行删除操作
{for(j=i;
length;
//ai至an依次前移
Elem[j-1]=elem[j];
length--;
//表长减一
return1;
//删除成功,返回
return
0;
//未找到,删除不成功,返回
2.分析顺序表中元素定位算法
intSqList<
Locate(Te)解:
设表长为
n,等概率下,每个元素被定位的概率为:
p=1/n
的时间复杂度。
定位成功第i
个元素,需比较i次
f(n)
n(n1)
n1
3.对于有头结点的单链表,分别写出定位成功时,实现下列定位
语句序列。
(1)定位到第i个结点ai;
(2)定位到第i个结点的前驱ai-1;
p=head;
j=0;
while(p&
&
i){p=p->
next;
j++;
i-1){p=p->
(3)定位到尾结点;
while(p->
next)
p=p->
(4)定位到尾结点的前驱。
while(p->
next->
4.描述一下三个概念的区别:
头指针,头结点,首元结点。
并给
头指针:
是一个指针变量,里面存储的是链表中首结点的地址,并以此来标识一个链表。
予图示。
头结点:
附加在第一个元素结点之前的一个结点,头指针指向头结点。
首元结点:
指链表中的第一个元素结点。
头指针
头结点
首
(元)结点
尾(元)结点
⋯...an^
a
a2
5.
对于无头结点单链表,给出删除第
i个结点的算法描述。
template<
calssT>
TLinkList<
Delete(inti)
{//在单链表上删除第
i个数据元素
if(head==NULL)throw
“表空!
”;
//空表,不能删
elseif(i==1)
{//删除第
1个元素
p=Head;
x=p->
data;
保存被删元素值
Head=p->
next;
deletep;
else{//元素定位到第ai-1
j=1;
//
定位查找起始位置
while{p->
next&
i-1}{
j++;
}
if(!
p->
next||j>
i-1);
定位失败
throw“删除位置不合理”;
else{//定位成功,进行结点删除
q=p->
x=p>
next=q->
deleteq;
retrunx;
//返回被删除元素值
}//#
6.
用教材定义的顺序表的基本操作实现下列操作:
#include“SqList.h“
intDeleteElem(SqListL,Te)
intDeleteElem(SqListL,Te){//
i=L.LocateElem(e);
//按值查找
7.已知L是有表头结点的单链表,且P结点既不是首元结点,也不是尾结点,试写出实现下列功能的语句序列。
(1)在P结点后插入S结点;
(2)在P结点前插入S结点;
(3)在表首插入S结点;
(4)在表尾插入S结点.
编程实现:
删除单链表中值为e的元素。
if(!
i)//未找到
return0;
else//找到
delete(i);
//删除被找到的元素
【解】
(1)s->
next=p->
p->
next=s;
(2)q=L;
while(q->
next!
=p)q=q->
s->
next=p或q->
q->
(3)s->
next=L->
L->
(3)q=L;
=NULL)q=q->
next=q->
q->
第3章栈与队列
1.铁路进行列车调度时,常把站台设计成栈式结构的站台,如右图所示。
试问:
若进站的六辆列车顺序如上所述,那么是否能够得到325641和154623的出站序列,如果不能,说明为什么不能;
如果能,说明如何得到(即写出"
进栈"
或"
出栈"
的序列)。
325641可以
154623不可以。
123456
2.简述以下算法的功能(栈的元素类型为
int)。
(1)借助一个数组,将栈中的元素逆置。
(1)statusalgo_1(SqStackS){
inti,n,A[255];
n=0;
while
(!
S.StackEmpty())
{n++;
A[n]=S.Pop();
}
(2)借助栈T,将栈S中所有值为e的数据元素删除之。
for(i=1;
=n;
i++)S.Push(A[i]);
(2)statusalgo_2(SqStackS,inte){
SqStackT;
intd;
S.tackEmpty())
{
d=S.Pop();
if
(d!
=e)T.Push(d);
T.StackEmpty())
d=T.Pop();
T.Push(d);
3.编写一个算法,将一个非负的十进制整数N转换为B进制数,
并输出转换后的结果。
当N=248D,B分别为8和16时,转换后的结果为多少?
#include“stack.h”
intNumTrans(intN,intB){//十进制整数N转换为B进制数stack<
int>
S;
//建立一个栈
while(N!
=0){//N非零
i=N%B;
//从低到高,依次求得各位
N=N/B;
S.push(i);
}//各位入栈
while(!
S.StackEmpty()){//
栈不空
{i=S.pop();
If(i>
9)i=
’A’+10-i;
cout<
<
S.pop();
}//依次出栈,得到从高到低的输出结果
4借且栈,设计算法:
假设一个算术表达式中包含
“(、”“)括”号,解:
以字符串存储表达式,也可以边输入边判断。
对一个合法的数学表达式来说,括号
“(和”“)应”是相互匹配的。
顺序扫描表达式,左括号,入栈;
右括号,如果此时栈空,表示多右括号,不匹
若匹配,返回1;
配;
如果栈不空,出栈一个左括号。
扫描结束,如果栈空,表示括号匹配;
否则,括
号不匹配,多左括号。
intblank_match(char*exp)
用字符串存表达式
SqStack<
char>
s;
创建一个栈
char*p=exp;
工作指针p指向表达式首
while(*p!
=’=’)
{//
不是表达式结束符
switch(p){
case’(’:
//左括号,入栈
s.push(ch);
break;
case’)’//右括号
if(s.StackEmpty())
//栈空,不匹配,多右括号
else{s.Pop();
break;
}//左括号出栈
}//switch
p++;
//取表达式下一个字符
}//while
s.StackEmpty())//表达式结束,栈不空
return0;
//不匹配,多左括号
else
//匹配
}//#
5.简述栈和队列的逻辑特点,各举一个应用实例。
6.写出下列中缀表达式的后缀表达式。
A-B+C-D+
(1)-A+B-C+D
AB+D*EFAD*+/+C+
(2)(A+B)*D+E/(F+A*D)+C
(3)
AB&
EF!
||
(3)A&
B||!
(E>
F)
7.计算后缀表达式:
45*32+-
的值。
15
8.将下列递推过程改写为递归过程。
voidrecurision(intj)
voidrecursion(intn){
inti=n;
while(i>
1){
{if(j>
{cour<
j;
recurision(j-1);
i;
i--;
9..将下列递归过程改写为非递归过程。
voidtest(int&
sum)
voidtest(int&
sum){
{stackS;
//借助一个栈
intx;
cin>
>
x;
if(x==0)sum=0;
while(x){
else{
S.push(x);
test(sum);
sum+=x;
sum;
sum=0;
while(x=S.pop()){
sum+=x;
cout<
}//
10.简述以下算法的功能(栈和队列的元素类型均为int)。
解:
利用栈,将队列中的元素逆置
voidalgo(Queue&
Q)
StackS;
//创建一个栈
while(!
Q.QueueEmpty()){
d=DeQueue(Q);
S.Push(d);
S.StackEmpty()){
d=S.Pop();
Q.EnQueue(d);
12.假设以数组se[m]存放循环队列的元素,同时设变量rear和
front分别作为队首、队尾指针,且队首指针指向队首前一个位置,
队尾指针指向队尾元素处,初始时,rear==fornt==-1。
写出这样设计的循环队列入队、出队的算法。
采用教材队空与队满判别方法。
为了区分队空与队满条件,牺牲一个元素空间。
即:
rear==front,为队空;
rear==(front+1)%m,为队满。
voidEnQueue(TSe[],Te,intm){//入队
if(rear+1)%m=fornt){//队满,不能插入
throw“队满,不能插入!
”
rear=(rear+1)%m;
//队尾指针后移
se[rear]=e;
//元素入队
return;
TDnQueue(TSe[],intm){//出队
if(rear==fornt)//队空,不能出队!
throw“队空,不能出队!
front=(front+1)%m;
//指针后移,指向队首元素
e=se[front];
//取队首元素
returne;
给出问题分析、算法描述、源程序及运行截图,在线提交。
1.借助栈,实现单链表上的逆置运算。
第4章串
1.试问执行以下函数会产生怎样的输出结果?
voiddemonstrate()
StrAssign(s,'
THISISABOOK'
);
StrRep(s,StrSub(s,3,7),'
ESEARE'
StrAssign(t,StrConcat(s,'
S'
));
StrAssign(u,'
XYXYXYXYXYXY'
);
StrAssign(v,StrSub(u,6,3));
StrAssign(w,'
W'
“'
t=”<
t<
endl;
“v=”<
v;
“u=”<
StrRep(u,v,w);
}//demonstrate
2.设字符串S=‘aabaabaabaac'
,P=‘aabaac'
1)给出S和P的next值和nextval值;
2)若S作主串,P作模式串,试给出KMP算法的匹配过程。
3.算法设计
串结构定义如下:
structSString
t=THESEAREBOOKS
v=YXY
w=XWXWXW
1)S的next与nextval
值分别为
012123456789和002002002009,
p的next与nextval
012123和002003
2)利用KMP算法的匹配过程:
第一趟匹配:
aabaabaabaac
aabaac(i=6,j=6)
第二趟匹配:
(aa)baac
第三趟匹配:
(成功)(aa)baac
char*data;
//串首址
intlen;
//串长
intStrSize;
//存放数组的最大长度.
};
(1)编写一个函数,计算一个子串在一个字符串中出现的次数,如果不出现,则为0。
intstr_count(SStringS,SStringT)
(2)编写算法,从串s中删除所有和串t相同的子串。
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;
intSubString_Delete(SString&
s,SStringt)
//从串s中删除所有与t相同的子串,并返回删除次数
for(n=0,i=0;
=s.len-t.len;
i++)
for(j=0;
t.len&
s[i+j]==t[i];
j++);
if(j>
t.len)//找到了与t匹配的子串
for(k=i;
s.len-t.len;
k++)
s[k]=s[k+t.len];
//左移删除
(2)编写一个函数,求串s和串t的一个最长公共子串。
voidmaxcomstr(SString*s,SString*t)
s.len-=t.len;
n++;
//被删除次数增1}
}//for
returnn;
}//Delete_SubString
voidmaxcomstr(SString*s,SString*t){
intindex=0,len1=0,i,j,k,len2;
i=0;
//作为扫描s的指针
while(i<
s.len){
j=0;
//作为扫描t的指针
while(j<
t.len){
if(s.data[i]==t.data[j]){//序号为i,长度为len2的子串
len2=1;
//开始计数
for(k=1;
s.data[i+k]==t.data[j+k]&
s.data[i+k]!
=NULL;
len2++;
if(len2>
len1){//将较大长度者给index和