数据结构习题集参考答案Word下载.docx

上传人:b****6 文档编号:19473100 上传时间:2023-01-06 格式:DOCX 页数:64 大小:225.08KB
下载 相关 举报
数据结构习题集参考答案Word下载.docx_第1页
第1页 / 共64页
数据结构习题集参考答案Word下载.docx_第2页
第2页 / 共64页
数据结构习题集参考答案Word下载.docx_第3页
第3页 / 共64页
数据结构习题集参考答案Word下载.docx_第4页
第4页 / 共64页
数据结构习题集参考答案Word下载.docx_第5页
第5页 / 共64页
点击查看更多>>
下载资源
资源描述

数据结构习题集参考答案Word下载.docx

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

数据结构习题集参考答案Word下载.docx

typedefstruct

{intnum;

//学号

charname[8];

//姓名

floatscore;

/平均成绩

}node;

nodestudent[100];

3.第一层FOR循环判断n+1次,往下执行n次,第二层FOR执行次数为(n+(n-1)+(n-2)+…+1),第三层循环体受第一层循环和第二层循环的控制,其执行次数如下表:

i=123…n

j=nnnn…n

j=n-1n-1n-1n-1…

…………

j=333

j=222

j=11

执行次数为(1+2+…+n)+(2+3+…+n)+…+n=n*n(n+1)/2-n(n2-1)/6。

在n=5时,f(5)=55,执行过程中,输出结果为:

sum=15,sum=29,sum=41,sum=50,sum=55(每个sum=占一行,为节省篇幅,这里省去换行)。

4.解答:

(1)intlocate(dataytpeA[1..n],dateytpek)

{i=1;

while((i<

=n)&

&

(A[i]!

=k))i++;

if(i<

=n)return(i);

elsereturn(o);

}

最坏时间复杂度T(n)=O(n).

(2)VoidCZ_max(datatypeA[n],x,y)

{x=A[1];

y=A[1];

for(i=2;

i<

=n;

I++)

if(x<

A[i]{y=x;

x=A[i];

}/*替换最大值*/

elseif(y<

A[i]y=A[i];

/*替换次最大值*/

}

最坏情况时间复杂度T(n)=O(n).

第2章线性表

1.B

2.A

3.C

4.C

5..A

6.D

7.B

8.B

9.B

10.C

11.C

12.B

13.B

1.链表中的头结点仅起到标识的作用。

2.线性表采用链表存储时,结点和结点内部的存储空间可以是不连续的。

(√)

3.顺序存储方式插入和删除时效率太低,因此它不如链式存储方式好。

4.对任何数据结构链式存储结构一定优于顺序存储结构。

5.所谓静态链表就是一直不发生变化的链表。

6.线性表的特点是每个元素都有一个前驱和一个后继。

7.循环链表不是线性表.(×

8.线性表只能用顺序存储结构实现。

9.线性表就是顺序存储的表。

10.链表是采用链式存储结构的线性表,进行插入、删除操作时,在链表中比在顺序存储结构中效率高。

(√)

 

1. 

必定 

 

不一定 

2. 

头指针 

头结点指针域 

前驱结点指针域 

3.双向链表

4.nO(n)n/2O(n)

5..单链表循环链表双向链表

6.指针

7.(n-1)/2

8.py->

next=px->

next;

px->

next=py

9.42

10.i=1;

i≤L.last

11.

(1)L->

next=null∥置空链表,然后将原链表结点逐个插入到有序表中

(2)p!

=null∥当链表尚未到尾,p为工作指针

(3)q!

=null∥查p结点在链表中的插入位置,这时q是工作指针。

(4)p->

next=r->

next∥将p结点链入链表中

(5)r->

next=p∥r是q的前驱,u是下个待插入结点的指针。

12.

(1)(A!

=null&

B!

=null)∥两均未空时循环

(2)A->

element==B->

element∥两表中相等元素不作结果元素

(3)B=B->

link∥向后移动B表指针

(4)A!

=null∥将A表剩余部分放入结果表中

(5)last->

link=null∥置链表尾

1.试述头结点,首元结点,头指针这三个概念的区别.

参考答案:

在线性表的链式存储结构中,头指针指链表的指针,若链表有头结点则是链表的头结点的指针,头指针具有标识作用,故常用头指针冠以链表的名字。

头结点是为了操作的统一、方便而设立的,放在第一元素结点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等),有头结点后,对在第一元素结点前插入结点和删除第一结点,其操作与对其它结点的操作统一了。

而且无论链表是否为空,头指针均不为空。

首元结点也就是第一元素结点,它是头结点后边的第一个结点。

2.在单链表和双向链表中,能否从当前结点出发访问到任何一个结点?

在单链表中不能从当前结点(若当前结点不是第一结点)出发访问到任何一个结点,链表只能从头指针开始,访问到链表中每个结点。

在双链表中求前驱和后继都容易,从当前结点向前到第一结点,向后到最后结点,可以访问到任何一个结点。

3.一线性表存储在带头结点的双向循环链表中,L为头指针。

如下算法:

(1)说明该算法的功能。

(2)在空缺处填写相应的语句。

voidunknown(BNODETP*L)

{…

p=L->

q=p->

r=q->

next;

while(q!

=L)

{while(p!

=L)&

(p->

data>

q->

data)p=p->

prior;

prior->

next=r;

(1)______;

next=p->

prior=p;

(2)______;

(3)______;

q=r;

p=q->

(4)______;

}

1)本算法功能是将双向循环链表结点的数据域按值自小到大排序,成为非递减(可能包括数据域值相等的结点)有序双向循环链表。

2)

(1)r->

prior=q->

prior;

∥将q结点摘下,以便插入到适当位置。

(2)p->

next->

prior=q;

(2)(3)将q结点插入

(3)p->

next=q;

(4)r=r->

或r=q->

∥后移指针,再将新结点插入到适当位置。

五、算法设计题

1.[题目分析]在递增有序的顺序表中插入一个元素x,首先应查找待插入元素的位置。

因顺序表元素递增有序,采用折半查找法比顺序查找效率要高。

查到插入位置后,从此位置直到线性表尾依次向后移动一个元素位置,之后将元素x插入即可。

voidInsert(ElemTypeA[],intsize,ElemTypex)

∥A是有size个元素空间目前仅有num(num<

size)个元素的线性表。

本算法将元素x插入到线性表中,并保持线性表的有序性。

{low=1;

high=num;

//题目要求下标从1开始

while(low<

=high)∥对分查找元素x的插入位置。

{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;

∥将元素x插入。

}算法结束。

[算法讨论]算法中当查找失败(即线性表中无元素x)时,变量low在变量high的右面(low=high+1)。

移动元素从low开始,直到num为止。

特别注意不能写成for(i=low;

=num;

i++)A[i+1]=A[i],这是一些学生容易犯的错误。

另外,题中未说明若表中已有值为x的元素时不再插入,故安排在A[mid]==x时,用low(=mid+1)记住位置,以便后面统一处理。

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

2.解答:

(1)顺序表

分析:

将顺序表的第一个元素与最后一个元素互换,第二个元素与倒数第二个元素互换。

void 

invert(SeqList 

*L, 

int 

*num)

j;

ElemType 

tmp;

for(j=0;

j<

=(*num-1)/2;

j++)

{tmp=L[j];

L[j]=L[*num-j-1];

L[*num-j-1]=tmp;

(2)单链表

invert(LinkList 

L)

{

Node 

*p,*q,*r;

if(L->

next==NULL) 

return;

/*链表为空*/

p=L->

p->

next=NULL;

/*摘下第一个结点,生成初始逆置表*/

while(q!

=NULL) 

/*从第二个结点起依次头插入当前逆置表*/

r=q->

next=L->

L->

q=r;

3.解答:

(1)定位LOCATE(L,X)

在带头结点类单链表上实现的算法为:

intlocate_lklist(lklisthead,datatypex)

/*求表head中第一个值等于x的的序号,不存在这种结点时结果为0*/

{p=head->

j=1;

/*置初值*/

while((p!

=NULL)&

(p->

data!

=x))

{p=p->

j++}/*未达表结点又未找到值等于X的结点时经,继续扫描*/

if(p->

data==x)return(j);

elsereturn(0);

在无头结点的单链表上实现的算法为:

intWlocate(lklisthead,datatypeX)

/*求表head中第一个值等于x的结点的序号。

不存在这种结点时结果为0*/

{p=head;

j=1;

if(p->

data==X)return(j);

(2)按序号查找find(L,i)

在带头结点的单链表上实现的算法为:

pointerfind_lklist(lklisthead,inti);

{j=1;

p=head->

while((j<

1)&

(p!

=NULL)){p=p->

j++}

if(i==j)return(p);

elsereturn(NULL);

p=head;

(3)、插入INSERT(L,X,i)

在带头结点单链表上实现的算法为:

voidinsert_lklist(lklisthead,datatypex,intI)

/*在表haed的第i个位置上插入一人以x为值的新结点*/

{p=find_lklist(head,i-1);

/*先找第i-1个结点*/

if(p==NULL)reeor(“不存在第i个位置”)/*若第i-1个结点不存在,退出*/

else{s=malloc(size);

s->

data=x/*否则生成新结点*/

next/*结点*p在链域值传给结点*s的链域*/

next=s;

/*修改*p的链域*/

voidWinsert(lklisthead,dataytpeX,inti)

{if(i<

=0)error(“i<

=0”);

else{s=malloc(size);

data=X;

/*否则生成新结点*/

if(i==1){s->

next=head;

head=s;

else{p=wfind_lklist(lklisthead,i-1);

if(p==NULL)error(“i>

n+1”);

else{s->

(4)删除DELDTE(L,i)

voiddelete_lklist(lklisthead,inti)/*删除表head的第i个结点*/

{p=find_lklist(head,i-1)/*先找待删结点的直接前驱*/

if((p!

==NULL)&

next!

=NULL))/*若直接前趋存在且待结点存在*/

(q=p->

/*q指向待删结点*/

next=q->

next/*摘除待结点*/;

free(q);

/*释放已摘除结点q*/

elseerror(“不存在第i个结点”)/*否则给出相关信息*/

voidWdelete(lklisthead,inti)

/* 删除表head的第i个结点,若该链表仅有一个结点时,赋该结点指针NULL*/

=0)error(“I<=0”

else{if(i==0){q=head;

head=head->

else{p=wfind_lklist(head,i-1);

/*找链表head中第i-1结点指针*/

if(p!

=NULL)

{q=p->

p->

free(q);

elseerror(“不存在第I个结点”);

4.【解答】算法如下:

LinkList 

merge(LinkList 

A, 

LinkListB, 

LinkList 

C)

{Node 

*pa,*qa,*pb,*qb,*p;

pa=A->

/*pa表示A的当前结点*/

pb=B->

p=A;

/*利用p来指向新连接的表的表尾,初始值指向表A的头结点*/

while(pa!

=NULL 

&

pb!

/*利用尾插法建立连接之后的链表*/

qa=pa->

qb=qb->

next=pa;

/*交替选择表A和表B中的结点连接到新链表中;

*/

p=pa;

next=pb;

p=pb;

pa=qa;

pb=qb;

if(pa!

/*A的长度大于B的长度*/

if(pb!

/*B的长度大于A的长度*/

C=A;

Return(C);

5.[题目分析]在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。

本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。

因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。

voidDelete(ElemTypeA[],intn)

∥A是有n个元素的一维数组,本算法删除A中所有值为item的元素。

{i=1;

j=n;

∥设置数组低、高端指针(下标)。

while(i<

j)

{while(i<

j&

A[i]!

=item)i++;

∥若值不为item,左移指针。

if(i<

j)while(i<

A[j]==item)j--;

∥若右端元素值为item,指针左移

j)A[i++]=A[j--];

[算法讨论]因元素只扫描一趟,算法时间复杂度为O(n)。

删除元素未使用其它辅助空间,最后线性表中的元素个数是j。

若题目要求元素间相对顺序不变,请参见本章三、填空题25的算法。

6.分析设置两个指针,分别指向*S及其后继,然后按循环链表特性,顺序往下查找*s的

直接前趋,找到后删除;

voidDELETE_Xlklist(lklistS)

{p=s;

while(q->

nest!

=s)

{p=q;

q=q->

7.分析:

在链表L中依次取元素,若取出的元素是字母,把它插入到字母B中,然后在L中删除该元素;

若取出的元素是数字,把它插入到数字链D中,然后在L中删除该元素。

继续取下一个元素,直到链表的尾部。

最后B、D、L中分别存放的是字母字符、数字字符和其它字符。

设原表有头结点、头指针L,新建数字字符链D,字母字符链B,其它字符链R。

voidDISM_lklist(lklistL,lklistD,lklistB,lklistR)

{D=malloc(sizeof(int));

D->

next=D;

/*建D循环链表头结点*/

B=malloc(sizeof(char));

B->

next=B;

/*建B循环链表头结点*/

p=L;

q=p->

=null)

{if((q->

data<

=’9’)&

(q->

=’0’))

{p->

/*在表L中摘除q结点*/

q->

next=D->

/*将q结点插入D中*/

/*移动q指针*/

elseif(q->

=’z’)&

=’a’)||(q->

=’a’))

/*在表L中删除q结点*/

next=B->

/*将q结点插入B中*/

}else{p=q;

}/*移动q指针*/

next=L;

R=L;

/*使R为循环表*/

8.约瑟夫环问题

【解答】算法如下:

typedefstructNode

{

intpassword;

intnum;

structNode*next;

Node,*Linklist;

voidJosephus()

LinklistL;

Node*p,*r,*q;

intm,n,C,j;

L=(Node*)malloc(sizeof(Node));

/*初始化单向循环链表*/

if(L==NULL){printf("

\n链表申请不到空间!

"

);

return;

L->

r=L;

printf("

请输入数据n的值(n>

0):

scanf("

%d"

&

n);

for(j=1;

j++) 

/*建立链表*/

p=(Node*)malloc(sizeof(Node));

if(p!

请输入第%d个人的密码:

j);

C);

password=C;

num=j;

r->

next=p;

r=p;

printf("

请输入第一个报数上限值m(m>

m);

*****************************************\n"

出列的顺序为:

\n"

q=L;

while(n!

=1) 

/*计算出列的顺序*/

while(j<

m) 

/*计算当前出列的人选p*/

q=p;

/*q为当前结点p的前驱结点*/

p=p->

j++;

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

当前位置:首页 > 表格模板 > 合同协议

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

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