历年链表考题与答案.docx
《历年链表考题与答案.docx》由会员分享,可在线阅读,更多相关《历年链表考题与答案.docx(47页珍藏版)》请在冰豆网上搜索。
历年链表考题与答案
历年链表考题及答案
[2005秋II.14]设已建立了两条单向链表,这两链表中的数据已按从小到大的次序排好,指针h1和h2分别指向这两条链表的首结点。
链表上结点的数据结构如下:
structnode{
intdata;
node*next;
};
以下函数node*Merge(node*h1,node*h2)的功能是将h1和h2指向的两条链表上的结
点合并为一条链表,使得合并后的新链表上的数据仍然按升序排列,并返回新链表的首结点
指针。
算法提示:
首先,使newHead和q都指向首结点数据较小链表的首结点,p指向另一链
表首结点。
其次,合并p和q所指向的两条链表。
在q不是指向链尾结点的情况下,如果q
的下一个结点数据小于p指向的结点数据,则q指向下一个结点;否则使p1指向q的下一
个结点,将p指向的链表接到q所指向的结点之后,使q指向p所指向的结点,使p指向
p1所指向的链表。
直到p和q所指向的两条链表合并结束为止。
注意,在合并链表的过程
中,始终只有两条链表。
[函数]
(4分)
node*Merge(node*h1,node*h2)
{node*newHead,*p,*p1;
//使newHead和q指向首结点数据较小链表的首结点,
if((27)){newHead=h1;p=h2;}
else{newHead=h2;p=h1;}
p指向另一链表首结点
//h1->datadata
node*q=newHead;
//合并两条链表
while(q->next)
{if(q->next->datadata)
(28);//q=q->next
else
{(29);//p1=q->next
q->next=p;
q=p;
p=p1;
}
}
q->next=p;
(30);//returnnewNead
}
[2005春II.11]设已建立一条单向链表,指针head指向该链表的首结点。
结点的数据结构如下:
structNode{
intdata;
Node*next;
};
以下函数sort(Node*head)的功能是:
将head所指向链表上各结点的数据按data值从小
到大的顺序排序。
算法提示:
初始时,使p指向链表的首结点,从p之后的所有结点中找出data值最小
的结点,让p1指向该结点。
将p指向的结点的data值与p1指向的结点的data值进行交换。
让p指向下一个结点,依此类推,直至p指向链表的最后一个结点为止。
[程序]
(4分)
Node*sort(Node*head)
{Node*p=head,*p1,*p2;if(p==NULL)returnhead;while(p->next!
=NULL)
{p1=p;p2=p->next;while(p2!
=NULL)
{if()//p2->datadata
p1=p2;
p2=p2->next;
}
if(p!
=p1)
{
intt;
t=p->data;
p->data=
;
//p1->data
=t;
//p1->data
}
;
//p=p->next
}
returnhead;
}
[2004秋II.11]已建立一条无序链表,head指向链首。
链表上结点的数据结构为:
structNode
{doublenum;Node*next;
};
以下函数sort(Node*head)的功能为:
将参数head所指向链表上的各个结点,按num值
的升序排序,并返回排序后链表的链首指针。
算法提示:
先让h指向空链,依次从head所指向的链表上取下一个结点,然后将取下的结点插入到已排序的h所指向的链表上。
Node*sort(Node*head)
{if(head==0)returnhead;
Node*h,*p;
h=0;
while(head)
{p=head;
(27);//(27)head=head->next或head=p->next
Node*p1,*p2;
if(h==0)
{h=p;
(28)
;
//(28)p->next=0或h->next=0
}
elseif(
(29)
)
//(29)h->num>=p->num或p->num<=h->num
{p->next=h;h=p;
}
else
{p2=p1=h;
while(p2->next&&p2->numnum)
{p1=p2;p2=p2->next;
}
if(
(30)
)
//(30)p2->numnum或p->num>p2->num
{p2->next=p;p->next=0;
}
else
{p->next=p2;
p1->next=p;
}
}
}
return(h);
}
[2004春II.11]输入一行字符串,用单向链表统计该字符串中每个字符出现的次数。
方法是:
对该字符串中的每个字符,
依次查找链表上的结点。
若链表结点上有该字符,
则将该结点的
count值加1;否则产生一个新结点,存放该字符,置
count为1,并将该结点插入链首。
最
后,输出链表上的每个结点的字符及出现次数。
链表的结构如下图所示。
head
⋯
c
c
c
c
count
count
count
count
next
next
next
next
#include
structnode
{charc;intcount;
node*next;
};
voidprint(node*head)
{while(head)
{cout<<"字符:
"<c<<"\t出现"<count<<"次\n";
head=head->next;
}
}
voiddele(node*head)
{node*p;while(head!
=NULL){p=head;
head=(27);//(27)head->next
deletep;
}
}
node*search(node*head,charch)
{node*p;p=head;
while(p)
{if(p->c==ch)
{p->count++;break;}
(28);//(28)p=p->next
}
if(p==0)
{
p=newnode;
p->c=ch;
p->count=1;
if(head)
(29)
;
//(29)p->next=head
elsep->next=0;
(30)
;
//(30)head=p
}
returnhead;
}
voidmain(void)
{chars[300],*p=s;node*h=0;
charc;
cout<<"请输入一行字符串:
";
cin.getline(s,300);
while(c=*p++)h=search(h,c);
print(h);dele(h);
}
[2003秋II.12]
用链表实现对候选人的得票进行统计。
函数Statistic的输入参数:
head指向链
首,name存放候选人的姓名。
该函数的功能为:
若在链表的结点上找到
name,则将姓名为
name的结点上得得票数加
1;否则新建一个结点,初始化其姓名和的票数,并将新结点插
入链尾。
最后返回链表的首指针。
链表的结构如下图所示。
head
name
name
name
⋯
name
count
count
count
count
next
next
next
next
#include
#include
structNode
{charname[12];
intcount;
Node*next;
//候选人姓名
//计数候选人的得票
};
{Node*p1=head,*p2;
if(head==0)//空表,插入第1个结点
{head=newNode;strcpy(head->name,name);
head->count=1;
head->next=0;
}
else
//不是空表,进行结点数值查找
{while(p1)
{if((27))//找到了//strcmp(p1->name,name)==0
{p1->count++;
break;
}
else//不是待查结点,移动指针,准备下一结点查找
{p2=p1;
(28);//p1=p1->next
}
}
if(
{
(29))//待查结点不存在
p1=newNode;//在尾部插入新结点
strcpy(p1->name,name);
p1->count=1;
p1->next=0;
(30);//p2->next=p1
//p1==NULL
}
}
returnhead;
}
voidList(Node*head)//输出结果
{while(head)
{cout<name<<":
\t"<count<next;
}
}
voidFree(Node*head)//释放链表空间
{Node*p;
while(head)
{p=head;head=head->next;deletep;
}
}
voidmain()//连续输入得票候选人的姓名,以输入"0"结束
{Node*head=0;charname[12];
cout<<"输入得票候选人的姓名:
";cin>>name;
while(strcmp(name,"0")!
=0)
{head=Statistic(head,name);cout<<"输入得票候选人的姓名:
";
cin>>name;
}
cout<<"统计得票结果:
\n姓名得票数\n";
List(head);
Free(head);
}
[2003春II.14]以下程序使用递归函数实现单向链表操作,完成链表的创建、显示、释放链
表的结点。
#include
structnode
{floatdata;node*next;
};
voidShowChain(node*head)//依次输出每一个结点上的数据
{if(head)
{cout<data<if(head->next)ShowChain(_____________);
//head->next
}
}
voidAddNode(node*p,node*&head)
{if(head==NULL)head=___________;
//将
p所指向的结点插入链尾
//p
elseAddNode(p,head->next);
}
voidDeleteChain(node*head)//依次删除链表上的每一个结点
{node*p=head;
if(p)
{head=____________;//head->next
deletep;
if(head)DeleteChain(head);
}
}
voidmain(void)
{node*head=NULL,*temp;temp=newnode;while
(2)
{temp->next=NULL;cout<<"输入数据:
";
cin>>temp->data;
if(temp->data>0)AddNode(temp,head);//
新结点加入链表尾部
else
{
deletetemp;break;}
temp=________________;
//newnode
}
ShowChain(head);
DeleteChain(head);
}
[2002秋II.14]n个人围成一圈,他们的序号依次为
1到n,从第一个人开始顺序报数
1、2、
3、⋯、m,报到m者退出圈子,并输出退出圈子的人的序号。
接着再顺序报数,直到圈子
中留下一个人为止。
用一个有
n个结点的环形链表模拟围成一圈的人。
假定有10
个人围成
一圈,凡报到
5者退出圈子,则退出圈子人的序号依次为
5、10、6、2、9、8、1、4、7,
最后留在圈中的人是3号。
单向环形链表的结构如下图所示。
其中
head指向第一个人。
head
1
2
3
⋯⋯
10
#include
structNode{
intx;//围成一圈时,人的序号
Node*next;
};
Node*DelNode(Node*head,intm)//依次输出环形链表中凡报到m者的序号
{Node*p;intcount;
if(head==NULL)return_____________;//head
while(head!
=head->next)//直到链表上只有一个结点为止
{count=0;
while(count{count++;head=head->next;}
p=head->next;//删除p所指向的结点
head->next=_______________;//p->next
head=head->next;
cout<x<deletep;
}
returnhead;
}
voidmain(void)
//在主函数中,构造环形链表,调用
DelNode
函数依次输出报到
m的人的序号
{
Node*head,*p;
//最后输出留在圈中最后的人的序号
inti;
head=newNode;
head->x=1;
head->next=NULL;
p=head;
for(i=2;i<=10;i++)
{p->next=newNode;p=_______________;
//新结点加入链尾
//p->next
p->x=i;
}
p->next=_________________;
//构成循环链
//head
head=DelNode(head,5);
cout<<"最后的一个人为:
"<x<}
[2002春II.14]设链表上结点的数据结构定义如下:
structNODE{
intx;
NODE*next;
};
函数create()的功能为:
创建一个有序的链表(结点中x的值按升序排序),参数n为链表上要产生的结点的个数,函数返回该有序链表的头指针。
算法思想:
每产生一个新的结点,插入到链表的恰当位置,使得插入新结点以后的链表仍然保持有序。
_____________creat(intn)//NODE*或structNODE*
{NODE*p,*p1,*p2,*h=NULL;
inti=0;
if(n<1)returnNULL;
while(____________)//i{p=newNODE;
cin>>p->x;p->next=NULL;
if(_________________)h=p;
else
{p1=p2=h;
//h==NULL
或
!
h
while(p2&&_____________)
//(p->x)>=(p2->x)
{p1=p2;p2=p2->next;
}
if(p2==h){p->next=p2;h=p;}
else{p->next=p2;p1->next=p;}
}
i++;
}
returnh;
}
[2001秋II.14]设链表上结点的数据结构定义如下:
structPNODE
{intx;
PNODE*next;
};
设已建立了一条链表,h为链首指针。
函数DelAdd的功能为:
若链表上能找到结点的
x值为value,则从链表上删除该结点(假定链表上各个结点的值是不同的);否则构造一个
新结点,其x的值为value,并将新结点插入链尾。
该函数返回新链表的首指针。
[程序](4分)
PNODE*DelAdd(PNODE*h,intvalue)
{PNODE*p1,*p2;
intflag=0;
//
值为1
时,表示已删除值为
value的结点
p1=h;
while(p1&&flag==0)
{
if(p1->x==value)
{
flag=1;
if(p1==h)
{
h=
(27)
;deletep1;}
//p1->next
else
{
p2->next=
(28)
;deletep1;}
//p1->next
}
else
{
p2=p1;
p1=
(29)
;}
//p1->next
}
if(flag==0)
{p1=newPNODE;p1->x=value;
p1->next=0;
if(h==0)h==p1;
else(30)
;
//p2->next=p1
}
returnh;
}
[2001春II.13]下面程序中,函数padd的功能为调整pa指向的链表中结点的位置,使得所
有x值为偶数的结点出现在链表的前半部,所有x值为奇数的结点出现在链表的后半部。
本程序的输出为:
10,8,6,4,2,1,3,5,7,9。
如
#include
structNODE
{intx;
NODE*next;
};
NODE*padd(NODE*pa)
{NODE*p1,*p2,*p;p1=p2=pa;
while(p1)
{if(p1->x%2==0&&_________________)//p1!
=pa第1个结点为偶数时不取
{p=p1;p1=p1->next;
________________=p1;//从链表上取下偶数结点并插入链首//p2->next
p->next=pa;__________________;//pa=p
}
else{p2=p1;p1=p1->next;}
}
returnpa;
}
voidmain(void)
{NODEa[10]={{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}},*ha=a,*p;inti;
for(i=0;i<9;i++)a[i].next=______________;//拉成链表
a[9].next=NULL;
ha=padd(ha);
p=ha;
while(p)
{cout<x<<’,’p=p;->next;}
//&a[i+1]
cout<<’n’;
}
*[2000秋II.11]设结点的数据结构定义如下:
structPNODE
{
intx,y;
PNODE*next;
};
函数
新链表(pc
padd的功能为:
根据pa,pb指向的两个链表(按结点的y值升序排列)生成一个
为链首指针)。
新生成链表仍按y值升序排列。
生成新链表的规则为:
当在pa和
pb链表中发现y值相同的结点时,则在pc表中对应的两个结点的x值之和,新结点的
链表中增加一个新结点,新结点的x
y取值为pa或pb链表中对应结点的
取值为两链
y值。
PNODE*padd(PNODE*pa,PNODE*pb)
{PNODE*pcr,*pt,*pc=0;
while((27))//pa&&pb
{if(pa->y==pb->y)
{pt=new(28);//PNODE
pt->x=pa->x+pb->x;pt->y=pa->y;pt->next=NULL;
if(pc==NULL)pc=pcr=pt;
else
{pcr->next=pt;(29);}//pcr=pt;
pa=pa->next;pb=pb->next;
}
else
if((30))pb=pb->ne