数据结构第二版习题答案第3章教程文件.docx
- 文档编号:4831115
- 上传时间:2022-12-10
- 格式:DOCX
- 页数:17
- 大小:18.85KB
数据结构第二版习题答案第3章教程文件.docx
《数据结构第二版习题答案第3章教程文件.docx》由会员分享,可在线阅读,更多相关《数据结构第二版习题答案第3章教程文件.docx(17页珍藏版)》请在冰豆网上搜索。
数据结构第二版习题答案第3章教程文件
数据结构(第二版)习题答案第3章
3.1选择题
第3章线性表的链式存储
(1)两个有序线性表分别具有n个元素与m个元素且n≤m,现将其归并成一个有序表,
其最少的比较次数是(A)。
A.n
B.m
C.n−1
D.m+n
(2)非空的循环单链表head的尾结点(由p所指向)满足(C)。
A.p->next==NULLB.p==NULLC.p->next==headD.p==head
(3)在带头结点的单链表中查找x应选择的程序体是(C)。
A.node*p=head->next;while(p&&p->info!
=x)p=p->next;
if(p->info==x)returnpelsereturnNULL;
B.node*p=head;while(p&&p->info!
=x)p=p->next;returnp;
C.node*p=head->next;while(p&&p->info!
=x)p=p->next;returnp;
D.node*p=head;while(p->info!
=x)p=p->next;returnp;
(4)线性表若采用链式存储结构时,要求内存中可用存储单元的地址(D)。
A.必须是连续的
C.一定是不连续的
B.部分地址必须是连续的
D.连续不连续都可以
(5)在一个具有n个结点的有序单链表中插入一个新结点并保持单链表仍然有序的时间
复杂度是(B)。
A.O
(1)B.O(n)
C.O(n2)
D.O(nlog2n)
(6)用不带头结点的单链表存储队列时,其队头指针指向队头结点,其队尾指针指向队
尾结点,则在进行删除操作时(D)。
A.仅修改队头指针
C.队头、队尾指针都要修改
B.仅修改队尾指针
D.队头,队尾指针都可能要修改
(7)若从键盘输入n个元素,则建立一个有序单向链表的时间复杂度为(B)。
A.O(n)
B.O(n2)
C.O(n3)
D.O(n×log2n)
(8)下面哪个术语与数据的存储结构无关(D)。
A.顺序表B.链表C.散列表
D.队列
(9)在一个单链表中,若删除p所指结点的后续结点,则执行(A)。
A.p->next=p->next->next;B.p=p->next;p->next=p->next->next;
C.p->next=p->next;D.p=p->next->next;
(10)在一个单链表中,若p所指结点不是最后结点,在p之后插入s所指结点,则执行(B)。
A.s->next=p;p->next=s;B.s->next=p->next;p->next=s;
C.s->next=p->next;p=s;D.p->next=s;s->next=p;
3.2设计一个算法,求一个单链表中的结点个数。
【答】:
单链表存储结构定义如下(相关文件:
linklist.h)
#include
11
#include
typedefstructnode
{intdata;
structnode*next;
}linknode;
typedeflinknode*linklist;
/*尾插法创建带头结点的单链表*/
linklistcreatlinklist()
{linklisthead,r,x,s;
head=r=(linklist)malloc(sizeof(linknode));
printf("\n请输入一组以0结束的整数序列:
\n");
scanf("%d",&x);
while(x)
{s=(linklist)malloc(sizeof(linknode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
returnhead;
}
/*输出带头结点的单链表*/
voidprint(linklisthead)
{linklistp;
p=head->next;
printf("Listis:
\n");
while(p)
{printf("%5d",p->data);
p=p->next;
}
printf("\n");
}
基于上述结构定义,求单链表中的结点个数的算法程序如下:
intcount(linklisthead)
{intc=0;
linklistp=head;
while(p)
{c++;
12
p=p->next;
}
returnc;
}
3.3设计一个算法,求一个带头结点单链表中的结点个数。
【答】:
带头结点的单链表的存储结构定义同题3.2,实现本题功能的算法程序如下(3_3.c)
#include"linklist.h"
intcount(linklisthead)
{intc=0;
linklistp=head->next;
while(p)
{c++;
p=p->next;
}
returnc;
}
main()
/*测试函数*/
{linklisthead;
head=creatlinklist();
print(head);
printf("\nLengthofheadis:
%d",count(head));
getch();
}
当输入5个数据时,产生的输出结果如下图所示:
3.4设计一个算法,在一个单链表中值为y的结点前面插入一个值为x的结点。
即使值为x的
新结点成为值为y的结点的前驱结点。
【答】:
#include"linklist.h"
voidinsert(linklisthead,inty,intx)
{/*在值为y的结点前插入一个值为x的结点*/
linklistpre,p,s;
pre=head;
p=head->next;
13
while(p&&p->data!
=y)
{pre=p;
p=p->next;
}
if(p)/*找到了值为y的结点*/
{s=(linklist)malloc(sizeof(linknode));
s->data=x;
s->next=p;
pre->next=s;
}
}
voidmain()
{linklisthead;
inty,x;
/*测试程序*/
head=creatlinklist();/*创建单链表*/
print(head);/*输出单链表*/
printf("\n请输入y与x的值:
\n");
scanf("%d%d",&y,&x);
insert(head,y,x);
print(head);
}
程序的一种运行结果如下图所示:
3.5设计一个算法,判断一个单链表中各个结点值是否有序。
【答】:
#include"linklist.h"
intissorted(linklisthead,charc)
/*当参数c=’a’时判断链表是否为升序,当参数c=’d’是判断链表是否为降序*/
{intflag=1;
linklistp=head->next;
switch(c)
{case'a':
/*判断带头结点的单链表head是否为升序*/
14
while(p&&p->next&&flag)
{if(p->data<=p->next->data)p=p->next;
elseflag=0;
}
break;
case'd':
/*判断带头结点的单链表head是否为降序*/
while(p&&p->next&&flag)
{if(p->data>=p->next->data)p=p->next;
elseflag=0;
}
break;
}
returnflag;
}
intmain()/*测试程序*/
{linklisthead;
head=creatlinklist();
print(head);
if(issorted(head,'a'))printf("单链表head是升序排列的!
\n");
else
if(issorted(head,'d'))printf("单链表head是降序排列的!
\n");
elseprintf("单链表head是无序的!
\n");
}
程序运行时的三种输出结果如下图所示:
3.6设计一个算法,利用单链表原来的结点空间将一个单链表就地转置。
【答】:
#include"linklist.h"
voidverge(linklisthead)
{/*本函数的功能是就地倒置带头结点的单链表*/
15
linklistp,q;
p=head->next;
head->next=NULL;
while(p)
{q=p;
p=p->next;
/*每次从原表取一个结点插入到新表的最前面*/
q->next=head->next;
head->next=q;
}
}
intmain()
{linklisthead;
/*测试函数*/
head=creatlinklist();/*创建单链表*/
print(head);/*输出原单链表*/
verge(head);/*就地倒置单链表*/
print(head);/*输出倒置后的单链表*/
}
3.7设计一个算法,将一个结点值自然数的单链表拆分为两个单链表,原表中保留值为偶数的
结点,而值为奇数的结点按它们在原表中的相对次序组成一个新的单链表。
【答】:
#include"linklist.h"
linklistsprit(linklisthead)
{/*将带头结点的单链表head中的奇数值结点删除生成新的单链表并返回*/
linklistL,pre,p,r;
L=r=(linklist)malloc(sizeof(linknode));
r->next=NULL;
pre=head;
p=head->next;
while(p)
{if(p->data%2==1)
{pre->next=p->next;
r->next=p;
r=p;
p=pre->next;
}
else
{pre=p;
p=p->next;
}
/*删除奇数值结点*/
/*保留偶数值结点*/
16
}
}
r->next=NULL;
returnL;
/*置链表结束标记*/
intmain()
{linklisthead,L;
/*测试函数*/
head=creatlinklist();/*创建单链表*/
print(head);/*输出原单链表*/
L=sprit(head);/*分裂单链表head*/
printf("\n原单链表为:
\n");
print(head);/*输出倒置后的单链表*/
printf("\n分裂所得奇数单链表为:
\n");
print(L);
}
本程序的一组测试情况如下图所示。
3.8设计一个算法,对一个有序的单链表,删除所有值大于x而不大于y的结点。
【答】:
#include"linklist.h"
voiddeletedata(linklisthead,datatypex,datatypey)
{/*删除带头结点单链表中所有结点值大于x而不大于y的结点*/
linklistpre=head,p,q;
p=head->next;初始化*/
while(p&&p->data<=x)/*找第1处大于x的结点位置*/
{pre=p;
p=p->next;
}
while(p&&p->data<=y)/*找第1处小于y的位置*/
p=p->next;
q=pre->next;
pre->next=p;
pre=q->next;
/*删除大于x而小于y的结点*/
17
}
while(pre!
=p)
{free(q);
q=pre;
pre=pre->next;
}
/*释放被删除结点所占用的空间*/
voidmain()
{linklisthead,L;
datatypex,y;
/*测试函数*/
}
head=creatlinklist();/*创建单链表*/
print(head);/*输出原单链表*/
printf("\n请输入要删除的数据区间:
\n");
scanf("%d%d",&x,&y);
deletedata(head,x,y);
print(head);/*输出删除后的单链表*/
3.9设计一个算法,在双链表中值为y的结点前面插入一个值为x的新结点。
即使值为x的新
结点成为值为y的结点的前驱结点。
【答】:
首先定义双链表的数据结构,相关文件dlink.h,内容如下:
typedefintdatatype;/*预定义的数据类型*/
typedefstructdlink_node{/*双链表结点定义*/
datatypedata;
structdlink_node*llink,*rlink;
}dnode;
typedefdnode*dlinklist;/*双链表结点指针类型定义*/
/*尾插法创建带头结点的双链表*/
dlinklistcreatdlinklist(void)
{dlinklisthead,r,s;
datatypex;
head=r=(dlinklist)malloc(sizeof(dnode));/*建立双链表的头结点*/
head->llink=head->rlink=NULL;
printf("\n请输入双链表的内容:
(整数序列,以0结束)\n");
scanf("%d",&x);
while(x)/*输入结点值信息,以0结束*/
{s=(dlinklist)malloc(sizeof(dnode));
s->data=x;
s->rlink=r->rlink;/*将新结点s插入到双链表链尾*/
18
s->llink=r;
r->rlink=s;
r=s;
scanf("%d",&x);
}
returnhead;
}
/*输出双链表的内容*/
voidprint(dlinklisthead)
{dlinklistp;
p=head->rlink;
printf("\n双链表的内容是:
\n");
while(p)
{printf("%5d",p->data);
p=p->rlink;
}
}
本题的求解程序如下:
#include
#include"dlink.h"
voidinsertxaty(dlinklisthead,datatypey,datatypex)
{dlinklists,p;
/*首先在双链表中找y所在的结点,然后在y前面插入新结点*/
p=head->rlink;
while(p&&p->data!
=y)
p=p->rlink;
if(!
p)printf("\n双链表中不存在值为y的结点,无法插入新结点!
\n");
else/*插入值为x的新结点*/
{s=(dlinklist)malloc(sizeof(dnode));
s->data=x;
s->rlink=p;
s->llink=p->llink;
p->llink->rlink=s;
p->llink=s;
}
}
voidmain()
{dlinklisthead;
datatypex,y;
/*测试函数*/
19
head=creatdlinklist();
print(head);
printf("\n请输入要输入的位置结点值y:
\n");
scanf("%d",&y);
printf("\n请输入要输入的结点值x:
\n");
scanf("%d",&x);
insertxaty(head,y,x);/*在值为y的结点前插入值为x的新结点*/
print(head);/*输出新的双链表*/
getch();
}
本程序的一组测试情况如下图所示。
3.10设计一个算法,从右向左打印一个双链表中各个结点的值。
【答】:
本题的双链表定义同题3.9,实现从右向左打印双链表的各个结点的值可以用递归程序实
现如下:
#include
#include"dlink.h"
voidvprint(dlinklisthead)
{/*递归方法从右向左打印双链表的值*/
if(head->rlink)
{vprint(head->rlink);
printf("%5d",head->rlink->data);
}
}
voidmain()
{dlinklisthead;
/*测试函数*/
head=creatdlinklist();
print(head);
printf("\n从右向左打印的双链表的内容是:
\n");
20
vprint(head);
getch();
}
本程序的一组测试情况如下图所示。
3.11设计一个算法,将一个双链表改建成一个循环双链表。
【答】:
#include
#include"dlink.h"
/*将一个双链表改成循环双链表*/
voiddlinktocdlink(dlinklisthead)
{dlinklistr;
r=head;
while(r->rlink)
r=r->rlink;
head->llink=r;
r->rlink=head;
}
/*寻找尾结点*/
voidprintcdlink(dlinklisthead)
{/*打印双链表*/
dlinklistp;
p=head->rlink;
while(p!
=head)
{printf("%5d",p->data);
p=p->rlink;
}
}
intmain()
{dlinklisthead;
/*测试函数*/
head=creatdlinklist();
dlinktocdlink(head);
printf("\n循环双链表的内容是:
\n");
printcdlink(head);
}
21
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 第二 习题 答案 教程 文件