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

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

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

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

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

数据结构习题集参考答案

第1章绪论

一、单项选择题

1.①B②D。

2.C。

3.A。

4.A。

5.CA

6.C。

7.B

8.C

9.C

10.C

二、判断题(在各题后填写“√”或“×”)

1.线性结构只能用顺序结构来存放,非线性结构只能用非顺序结构来存放。

(×)

2.数据元素是数据的最小单位。

(×)

3.记录是数据处理的最小单位。

(×)

4.算法就是程序。

(×)

5.数据的逻辑结构是指数据的各数据项之间的逻辑关系;(×)

6.数据的物理结构是指数据在计算机内的实际存储形式。

(√)

7.在顺序存储结构中,有时也存储数据结构中元素之间的关系。

(×)

8.顺序存储方式的优点是存储密度大,且插入、删除运算效率高。

(×)

9.线性表若采用链式存储结构时,要求内存中可用存储单元的地址一定是不连续的。

(×)

10.数据的逻辑结构说明数据元素之间的顺序关系,它依赖于计算机的储存结构.(×)

三、填空题

1.逻辑结构物理结构操作(运算)算法

2.集合线性结构树形结构图状结构或网状结构

2.没有1没有1

4.前驱1后续任意多个

5.表示(又称映像)

6.顺序存储方式链式存储方式索引存储方式散列存储方式

7.

(1)逻辑特性

(2)在计算机内部如何表示和实现(3)数学特性

8.算法的时间复杂度和空间复杂度

9.

(1)有穷性

(2)确定性(3)可行性

10.1log2nnn22n实际不可计算高效

11.(n+3)(n-2)/2

11.①

(1)1

(2)1(3)f(m,n-1)(4)n②9

13.o(log2n)。

四、应用题

1.解答:

(1)图略。

线性结构

(2)图略。

树结构

(3)图略。

图结构

2.将学号、姓名、平均成绩看成一个记录(元素,含三个数据项),将100个这样的记录存于数组中。

因一般无增删操作,故宜采用顺序存储。

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

elseif(y

}

最坏情况时间复杂度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->next;q=p->next;r=q->next;

while(q!

=L)

{while(p!

=L)&&(p->data>q->data)p=p->prior;

q->prior->next=r;

(1)______;

q->next=p->next;q->prior=p;

(2)______;(3)______;q=r;p=q->prior;

(4)______;

}

}

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

2)

(1)r->prior=q->prior;∥将q结点摘下,以便插入到适当位置。

(2)p->next->prior=q;∥

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

(3)p->next=q;

(4)r=r->next;或r=q->next;∥后移指针,再将新结点插入到适当位置。

五、算法设计题

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

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

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

voidInsert(ElemTypeA[],intsize,ElemTypex)

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

本算法将元素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;i<=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)

 int 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)单链表

void invert(LinkList L)

 {

Node *p,*q,*r;

   if(L->next==NULL) return;         /*链表为空*/

   p=L->next;   

   q=p->next;              

p->next=NULL;             /*摘下第一个结点,生成初始逆置表*/

while(q!

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

  {

r=q->next;

q->next=L->next;

L->next=q;

q=r;

 }

}

3.解答:

(1)定位LOCATE(L,X)

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

intlocate_lklist(lklisthead,datatypex)

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

{p=head->next;j=1;/*置初值*/

while((p!

=NULL)&&(p->data!

=x))

{p=p->next;j++}/*未达表结点又未找到值等于X的结点时经,继续扫描*/

if(p->data==x)return(j);

elsereturn(0);

}

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

intWlocate(lklisthead,datatypeX)

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

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

{p=head;j=1;/*置初值*/

while((p!

=NULL)&&(p->data!

=x))

{p=p->next;j++}/*未达表结点又未找到值等于X的结点时经,继续扫描*/

if(p->data==X)return(j);

elsereturn(0);

}

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

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

pointerfind_lklist(lklisthead,inti);

{j=1;p=head->next;

while((j<1)&&(p!

=NULL)){p=p->next;j++}

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

elsereturn(NULL);

}

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

pointerfind_lklist(lklisthead,inti);

{j=1;p=head;

while((j<1)&&(p!

=NULL)){p=p->next;j++}

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

elsereturn(NULL);

}

(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/*否则生成新结点*/

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

p->next=s;/*修改*p的链域*/

}

}

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

voidWinsert(lklisthead,dataytpeX,inti)

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

{if(i<=0)error(“i<=0”);

else{s=malloc(size);s->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->next=p->next;p->next=s;}

}

}

(4)删除DELDTE(L,i)

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

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

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

if((p!

==NULL)&&(p->next!

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

(q=p->next;/*q指向待删结点*/

p->next=q->next/*摘除待结点*/;

free(q);/*释放已摘除结点q*/

}

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

}

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

voidWdelete(lklisthead,inti)

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

{if(i<=0)error(“I<=0”

else{if(i==0){q=head;head=head->next;free(q);}

else{p=wfind_lklist(head,i-1);/*找链表head中第i-1结点指针*/

if(p!

=NULL)&&(p->next!

=NULL)

{q=p->next;p->next=q->next;free(q);}

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

4.【解答】算法如下:

LinkList merge(LinkList A, LinkListB, LinkList C)

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

 pa=A->next;                   /*pa表示A的当前结点*/

 pb=B->next; 

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

                

 while(pa!

=NULL && pb!

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

{  qa=pa->next;

qb=qb->next;

 p->next=pa;  /*交替选择表A和表B中的结点连接到新链表中;*/

p=pa;

p->next=pb;

p=pb;                      

pa=qa;

pb=qb;

}

if(pa!

=NULL)  p->next=pa;     /*A的长度大于B的长度*/

if(pb!

=NULL)  p->next=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

{while(i

=item)i++;∥若值不为item,左移指针。

if(i

if(i

}

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

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

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

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

直接前趋,找到后删除;

voidDELETE_Xlklist(lklistS)

{p=s;q=p->next;

while(q->nest!

=s)

{p=q;q=q->next;}

p->next=s;free(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->next;

while(q!

=null)

{if((q->data<=’9’)&&(q->data>=’0’))

{p->next=q->next;/*在表L中摘除q结点*/

q->next=D->next;D->next=q;/*将q结点插入D中*/

q=p->next;/*移动q指针*/

}

elseif(q->data<=’z’)&&(q->data>=’a’)||(q->data<=’z’)&&(q->data>=’a’))

{p->next=q->next;/*在表L中删除q结点*/

q->next=B->next;B->next=q;/*将q结点插入B中*/

q=p->next;/*移动q指针*/

}else{p=q;q=p->next;}/*移动q指针*/

}

p->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->next=NULL;

 r=L;     

 printf("请输入数据n的值(n>0):

");

 scanf("%d",&n);

 for(j=1;j<=n;j++)                             /*建立链表*/

  {

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

     if(p!

=NULL)

       {

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

",j);

         scanf("%d",&C);

         p->password=C;

         p->num=j;

         r->next=p;

        r=p;

    }

  }

 r->next=L->next;

printf("请输入第一个报数上限值m(m>0):

");

 scanf("%d",&m);

 printf("*****************************************\n");

 printf("出列的顺序为:

\n");

 q=L;

 p=L->next;

 while(n!

=1)                       /*计算出列的顺序*/

 {

        j=1;

      while(j

      {

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

            p=p->next;

            j++;

   

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

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

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

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