数据结构课本习题答案.docx

上传人:b****4 文档编号:24381049 上传时间:2023-05-26 格式:DOCX 页数:66 大小:391.98KB
下载 相关 举报
数据结构课本习题答案.docx_第1页
第1页 / 共66页
数据结构课本习题答案.docx_第2页
第2页 / 共66页
数据结构课本习题答案.docx_第3页
第3页 / 共66页
数据结构课本习题答案.docx_第4页
第4页 / 共66页
数据结构课本习题答案.docx_第5页
第5页 / 共66页
点击查看更多>>
下载资源
资源描述

数据结构课本习题答案.docx

《数据结构课本习题答案.docx》由会员分享,可在线阅读,更多相关《数据结构课本习题答案.docx(66页珍藏版)》请在冰豆网上搜索。

数据结构课本习题答案.docx

数据结构课本习题答案

数据结构

第一章绪论

一、单项选择题

1、

(1)A

(2)B2、

(1)B

(2)D3、C4、A5、A6、

(1)C

(2)A7、

(1)C

(2)A8、C9、C10、B11、D

二、填空题

1、存储结构、算法

2、非线性结构

3、线性、树型、图形

4、映射

5、线性结构、树型结构、图形结构

6、有穷性、确定性、可行性

7、错误

三、算法分析

1、

(1)O(n)、

(2)O(n)、(3)O(n)、(4)O(n)、

(5)O(

)、(6)O(log3n)、(7)O(log2n)

2、

(1)order()函数是一个递归排序过程,设T(n)是排序n个元素所需要的时间。

在排序n个元素时,算法的计算时间主要花费在递归调用order()上。

第一调用时,处理的元素序列个数为n-1,也就是对余下的n-1个元素进行排序,所需要的计算时间应为T(n-1)。

又因为在其中的循环中,需要n-1次比较。

所以排序n个元素所需要的时间为:

T(n)=T(n-1)+n-1n﹥1

据此可得:

T

(1)=0

T

(2)=T

(1)+1=0+1=1

T(n)=T(n-1)+n-1n﹥1

求解过程为:

T(n)=[T(n-2)+(n-2)]+n-1

=[T(n-3)+(n-3)]+(n-2)+n-1

=…

=(T

(1)+1)+2+…+n-1

=0+1+2+…+n-1

=n(n-1)/2

=O(n2)

故order函数的时间复杂度为O(n2)

(2)解:

设fact(n)数是T(n)。

该函数中语句If(n≤1),return1;的运行时间是O

(1),语句return(n*fact(n-1));运行时间是T(n-1)+O

(1),其中O

(1)为乘法运算的时间。

因此

T(n)=O

(1)n≤1

T(n)=T(n-1)+O

(1)n>1

则T(n)=O

(1)+T(n-1)

=2*O

(1)+T(n-2)

=…

=(n-1)*O

(1)+T

(1)

=n*O

(1)

=O(n)

即fact(n)的时间复杂度为O(n)。

(3)解:

设Fn的时间复杂度为T(n),有:

T(n)=T(n-1)+T(n-2)<2T(n-1)

<2

T(n-2)<…

<2

T(0)

=O(2

又:

T(n)=T(n-1)+T(n-2)>2T(n-2)

>2

T(n-4)>…

>2

T

(1)(n为奇数时,或2

T(0),n为偶数时)

即:

T(n)>O(2

则:

O(2

)<T(n)<O(2

取最坏情况上限,即T(n)=O(2

)。

第二章、线性表

一、单项选择题

1、A2、B3、C4、A5、D6、D7、D8、B9、B10、C11、A12、A13、A14、D15、C16、B17、B18、D

二、判断题

1、F2、T3、F4、F5、F6、F7、F8、F9、F10、F

三、填空题

1、顺序

2、n-1/2

3、py→next=px→next;px→next=py;

4、n-i+1

5、

(1)便于处理首元结点,使得在创建链表和删除结点时,可以将首元结点与其他结点同等对待。

(2)利用头结点的数据域存储链表的相关信息

6、O

(1)O(n)

7、单链表和多重链表动态链表和静态链表

8、f→next=p→next;f→prior=p;p→next→prior=f;p→next=f;

9、指针

10、物理上相邻指针

四、简答题

1、

(1)由于链式存储结构可以用任意的存储空间来存储线性表中的各数据元素,且其存储空间可以是连续的,也可以是不连续,此外,这种存储结构对元素进行插入和删除操作时都无需移动元素,而仅仅修改指针即可,所以很适用于线性表容量变化的情况。

(2)由于顺序存储结构一旦确定了起始位置,线性表中的任何一个元素都可以进行随机存取,即存取速度较高;并且,由于线性表的总数基本稳定,且很少进行插入和删除,故这一特点恰好避开了顺序存储结构的缺点,因此,应选用顺序存储结构。

2、不一定,由于链式存储需要额外的空间来存储指针,所以要比顺序存储多占用空间。

在空间允许的情况下,链式存储结构可以克服顺序存储结构弱点,但空间不允许时,链表存储结构会出现新的问题。

3、该线性表宜采用链表存储结构。

因为采用链式存储结构的线性表,插入和删除操作只需要改变指针,时间复杂度为O

(1),而采用顺序存储结构的线性表插入和删除涉及到数据的大量移动,时间复杂度为O(n)

4、线性结构包括线性表、栈、队列、串,线性表的存储结构又分成顺序存储和链式存储。

用C语言描述

顺序存储类型:

Typedefstruct

{

ElemTypedata[maxlen];//存放元素

intlen;//存放长度

}Sqlist;

链式存储类型:

Typedefstructnode

{

ElemTypedata;//数据域

structnode*next;//指针域

}SNode;

5、先找到值为23和15的两个结点,q指向值为23的结点,p指向值为15的结点,p和q结点互换:

q→llink→rlink=p;p→llink=q→llink;

p→rlink=q;q→llink=p;q→rlink!

=null;

6、

(1)p→rlink→llink=p→llink;

p→llink→rlink=p→rlink;

dispose(p);

(2)new(q);

q→llink=p;

q→rlink=p→rlink;

p→rlink→llink=q;

p→rlink=q;

五、算法分析

1、VoidInsert(Lnode*head,ElemTypex,ElemTypey)

{

Lnode*q,p;

q=head;

p=q→next;

while(p→data!

=x&&p!

=null)

{q=p;

p=p→next;

}

if(p==null)

p→next=s;

elses=(Lnode*)malloc(sizeof(Lnode));

s→data=x;

s→next=p;

q→next=s;

}

2、VoidgetVoionList(SqList&A,SqList&B,SqList&C)

{nodepa,pb,pc,q;

pa=A→next;pb=B→next;

C=A;

A→next=null;

while(pa!

=null&&pb!

=null)

{if(pa→data<=pb→data)

{q=pa;pa=pa→next;q→next=C→next;C→next=q;

}else

{q=pb;pb=pb→next;q→next=C→next;C→next=q;

}

}

if(pa!

=null)

{

while(pa!

=null)

{q=pa;pa=pa→next;q→next=C→next;C→next=q;

}

}

if(pb!

=null)

{

while(pb!

=null)

{q=pb;pb=pb→next;q→next=C→next;C→next=q;

}

}

}

3、StatechangeList(SqList&heada,SqList&headb,inti,intlenintj)

{node*a,*b,p,q;

a=heada;b=headb;

count=1;

if(i==1)

{for(k=1;k<=len;k++)

{q=heada

if(q==NULL)returnError;

heada=heada→next;free(q);

}

}else

{

while(a!

=null&&count

{a=a→next;count++;}

if(a==NULL)returnError;

for(k=1;k<=len;k++)

{

q→a→next;

if(q==NULL)returnError;

a→next=q→next;free(q);

}

}

if(pa==NULL)returnok;

p=pa;

while(p→next!

=NULL)p=p→next;

if(j==1)

{p→next=headb;headb=heada;}

else

{q=headb;count=1;

while(q!

=null&&count

{q→q→next;count++;}

If(q==NULL)returnError;

p→next=q→next;q→next=heada;

}

returnok;

}

4、在递增有序的顺序表中插入一个元素x,首先应查找待插入元素的位置。

因顺序表元素递增有序,采用折半查找法比顺序查找效率高,查到插入位置后,从此位置直到线性表尾依次向后移动一个元素位置,之后将元素X插入即可。

查找算法的时间复杂度为O(logn),而插入时的移动操作的时间复杂度为O(n),若用顺序查找,则查找的时间复杂度为O(n)。

VoidInsert(ElemTypeA[],intsize,ElemTypex)

{low=1;high=num;

while(low<=high)

{mid=(low+high)/2;

if(A[mid]==x)

{low=mid+1;break;}

elseif(A[mid]>x)high=mid-1;

elselow=mid+1;

}

for(i=num;i>=low;i--)

A[i+1]=A[i];

A[i+1]=x;

}

5、Structpnode

{

intcoef;//系数

intexp;//指数

Structpnode*Link;

};

Structpnode*padd(Structpnode*heada,Structpnode*headb)

{

Structpnode*headc,*p,*q,*r,*s;

intx;

p=heada;q=headb;

headc=(Structpnode*)malloc(sizeof(Structpnode));

r=headc;//R始终指向新链表中的最后一个节点

while(p!

=NULL&&q!

=NULL)

{if(p→exp==q→exp)//两指数相等时,将两系数相加生成一新节点插入C中

{x=p→coef+q→coef;

if(x!

=0)

{s=(Structpnode*)malloc(sizeof(Structpnode));

s→coef=x;s→exp=p→exp;

r→Link=s;r=s;

}

p=p→Link;q=q→Link;

}

p=p→Link;q=q→Link;

}

elseif(p→exp

{s=(Structpnode*)malloc(sizeof(Structpnode));

s→coef=q→coef;s→exp=p→exp;

r→Link=s;r=s;

q=q→Link;

}

else

{s=(Structpnode*)malloc(sizeof(Structpnode));

s→coef=q→coef;s→exp=p→exp;

r→Link=s;r=s;

p=p→Link;

}

}

if(p!

=NULL)q=p;

while(q!

=NULL)

{s=(Structpnode*)malloc(sizeof(Structpnode));

r→Link=s;

r=s;q=q→Link;

}

r→Link=NULL;

s=headc;

headc=headc→Link;

free(s);

return(headc);

}

第三章、栈和队列

一、单项选择题

1、C2、B3、D4、C5、D6、A7、B8、C9、B10、D11、C12、D13、B14、C15、A16、A17、A18、C19、A20、D

二、填空题

1、栈

2、队尾、队首、栈顶、栈顶

3、删除运算的不同

4、先移动栈顶指针,后存入元素

5、先取出元素,后移动栈顶指针

6、不可能的

7、可能的

8、O

(1)

9、S=NULL

10、先取出元素,后移动队尾指针

11、先存放元素,后移动队尾指针

12、MAX-1

13、ST→front==ST→rear

三、简答题

1、解:

Initstack(st);//空栈

Push(st,‘A’);//栈内容:

A

Push(st,‘B’);//栈内容:

A、B

Push(st,‘C’);//栈内容:

A、B、C

Pop(st,x);//栈内容:

A、B

Pop(st,x);//栈内容:

A

Push(st,‘D’);//栈内容:

A、D

Push(st,‘E’);//栈内容:

A、D、E

Push(st,‘F’);//栈内容:

A、D、E、F

Pop(st,x);//栈内容:

A、D、E

Push(st,‘G’);//栈内容:

A、D、E、G

Pop(st,x);//栈内容:

A、D、E

Pop(st,x);//栈内容:

A、D

Pop(st,x);//栈内容:

A

2、解,本题利用栈的“后进先出”的特点,有如下几点情况:

A进,A出,B进,B出,C进,C出,产生输出序列ABC

A进,A出,B进,C进,C出,B出,产生输出序列ACB

A进,B进,B出,A出,C进,C出,产生输出序列BAC

A进,B进,B出,C进,C出,A出,产生输出序列BCA

A进,B进,C进,C出,B出,A出,产生输出序列CBA

不可能的输出序列CAB

3、解显示队列中的内容如下:

InitQueue(Q);//空队列

AddQ(Q,‘A’);//队中内容:

A

AddQ(Q,‘B’);//队中内容:

A、B

AddQ(Q,‘C’);//队中内容:

A、B、C

Del(Q);//队中内容:

B、C

Del(Q);//队中内容:

C

AddQ(Q,‘D’);//队中内容:

C、D

AddQ(Q,‘E’);//队中内容:

C、D、E

AddQ(Q,‘F’);//队中内容:

C、D、E、F

Del(Q);//队中内容:

D、E、F

AddQ(Q,‘G’);//队中内容:

D、E、F、G

Del(Q);//队中内容:

E、F、G

Del(Q);//队中内容:

F、G

Del(Q);//队中内容:

G

4、当元素d、e、b、g、h入队后,rear=5,front=0;元素d,e出队,rear=5,front=2;元素i、j、k、l、m入队后,rear=10,front=2;元素b出队,rear=10,front=3;此时若再让n、o、p入队,由于rear=10,故队列溢出,入队和出队的变化函数如下图所示:

(a)初始状态(b)元素d、e、b、g、h入队(c)元素d、e出队

(d)元素i、j、k、l、m入队(e)元素b出队

5、解当元素d、e、b、g、h入队后,rear=5,front=0;元素d,e出队,rear=5,front=2;元素i、j、k、l、m入队后,rear=10,front=2;元素b出队,rear=10,front=3;此时若再让n、o、p入队,rear=2,front=3;队列不会溢出。

(a)初始状态(b)元素d、e、b、g、h入队(c)元素d、e出队

(d)元素i、j、k、l、m入队(e)元素b出队(f)元素n、o、p入队

四、算法分析

1、解假设采用顺序栈结构。

先退栈ST中所有元素,利用一个临时栈tmpst存放从ST栈中退出的元素,最后的一个元素即为所求,然后将临时栈tmpst中的元素逐一出栈并进栈到ST中,这样恢复ST栈中原来的元素。

算法如下:

ElemTypebottom(stackST)

{

ElemTypeX,Y;

Stacktmpst;

InitStack(tmpst);//初始化临时栈

while(!

StackEmpty(ST))//临时栈tmpst中包含ST栈中逆转元素

{pop(ST,x);

push(tmpst,x);

}

While(!

StackEmpty(tmpst))//恢复ST栈中原来的内容

{pop(tmpst,y);

push(ST,y);

}

returnx;

}

2、解:

假设栈不带头结点,求栈中元素个数算法如下:

Intcount(SNode*top)

{

SNode*p=top;

intn=0;

while(!

=NULL)

{n++;

p=p→next;

}

return(n);

}

3、解:

假设是循环顺序队列,建立一个临时栈tmpst,将指定队列Q中的所有元素出队并入栈到tmpst栈中,这样Q中队列为空,再将栈tmpst中的所有元素出栈并入队Q中,这样Q队列中的内容发生了反转。

算法如下:

Viodreverse(Queue&Q)

{

ElemTypex;

Stacktmpst;

InitStack(tmpst);//初始化栈tmpst

while(!

QueueEmpty(Q))

{DeQueue(Q,x);

push(tmpst,x);

}

while(!

QueueEmpty(tmpst))

{pop(tmpst,x);

EnQueue(Q,x);

}

}

4、解:

假设是循环顺序队列,没有取队尾元素的基本运算。

建立一个临时队列tmpqu,将指定队列qu的所有元素出队并如队到tmpqu这样qu队列为空,再将队列tmpqu中的所有元素出队并入队到qu队中,最后的一个元素即为所求。

算法如下:

ElemTypelast(Queuequ)

{

ElemTypex;

queuetmpqu;

initQueue(tmpqu);

while(!

QueueEmpty(qu))

{DeQueue(qu,x);

EnQueue(tmpqu,x);

}

while(!

QueueEmpty(tmpqu))

{DeQueue(tmpqu,x);

EnQueue(qu,x);

}

returnx;

}

5、解:

该共享栈的结构如下图所示:

两栈的最多元素个数为m,top1是栈1的栈指针,top2是栈2的栈指针,当top2=top1+1时出现上溢出,当top1=0时栈1出现下溢出,当top2=m+1时栈2出现下溢出。

算法如下:

//top1,top2和m均为已赋初值的int全局变量

Intpush(ElemTypex,inti)

{if(top1==top2-1)//上溢出

return0;//返回出错信息

elseif(i==1)//对第一个栈进行进栈操作

{top1++;

C[top1]=x;

}

else//对第二个栈进行进栈操作

{top2--;

C[top2]=x;

}

return1;//返回成功信息

}

intpop(inti,ElemType&x)

{if(i==1)//对第一个栈进行出栈操作

{if(top1==0)//栈1下溢出

return0;//返回出错信息

else

{x=c[top1];

top1--;

}

}

else//对第二个栈进行出栈操作

{if(top2==m+1)//栈2下溢出

return0;//返回出错信息

else

{x=c[top2];

top2++;

}

}

return1;//返回成功信息

}

Voidsetnull(inti)

{if(i==1)

top1=0;

else

top2=m+1;

}

6、解:

定义队列类型如下:

Typedefstruct

{

SNode*rear;

}QType2;

(1)队列插入一个结点的操作是在队尾进行的,所以应在该循环链队的尾部插入一个结点,算法如下:

EnQueue(QType2*&qu,ElemTypex)//向队列中插入X结点

{SNode*s;

s=(SNode*)malloc(sizeof(SNode));//建立一个新结点

s→data=x;

if(qu→rear==NULL)//循环队列为空,则建立一个结点的循环队列

{qu→rear=s;

qu→rear→next=s;

}

else//循环队列不为空,则将*S插到后面

{s→next=qu→rear→next;

qu→rear→next=s;

qu→rear→nextrear=s;//qu→rear始终指向最后一个结点

}

}

(2)队列的删除结点是在队头进行的,所以删除该循环链表的第一个结点,算法如下:

IntDeQueue(QType2*&qu,ElemType&x)

{SNode*p;

if(qu→rear==NULL)//队列下溢出

return0;//返回出错信息

else

{p=qu→rear→next;//p指向队头结点

x=p→data;

if(p==qu→rear)//队列只有一个结点,则直接删除该结点

qu→rear==NULL;

else

qu→rear→next=p→next;//否则删除第一个结点

free(p);//释放队头结点

return1;//返回成功信息

}

}

7、解:

求该链队中结点个数实际上是计算以top→front为头指针的单链表中结点个数。

算法如下:

IntQucount(LQueue*top)

{SNode*p=top→front;

intn=0;

while(p!

=NULL)

{n++;

p=p→next;

}

return(n);

}

8、解:

写递归函数要清楚结束递归的

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1