C++链表基本操作Word格式.docx
《C++链表基本操作Word格式.docx》由会员分享,可在线阅读,更多相关《C++链表基本操作Word格式.docx(18页珍藏版)》请在冰豆网上搜索。
下面我们给出上述链表的输出函数;
voidlist:
:
outputlist()
Node*current=head;
while(current!
=NULL)
cout<
<
current->
Data<
"
;
current=current->
next;
endl;
3.链表结点的插入
如果要在链表中的结点a之前插入结点b,则需要考虑下面几点情况。
(1)插入前链表是一个空表,这时插入新结点b后。
(2)若a是链表的第一个结点,则插入后,结点b为第一个结点。
(3)若链表中存在a,且不是第一个结点,则首先要找出a的上一个结点a_k,然后使a_k的指针域指向b,在令b的指针域指向a,即可完成插入。
(4)如链表中不存在a,则插在最后。
先找到链表的最后一个结点a_n,然后使a_n的指针域指向结点b,而b指针的指针为空。
以下是链表类的结点插入函数,显然其也具有建立链表的功能。
insertlist(intaDate,intbDate)//设aDate是结点a中的数据,bDate是结点b中的数据
?
Node*p,*q,*s;
//p指向结点a,q指向结点a_k,s指向结点b
s=(Node*)new(Node);
//动态分配一个新结点
s->
Data=bDate;
//设b为此结点?
p=head;
if(head==NULL)//若是空表,使b作为第一个结点
head=s;
next=NULL;
else
if(p->
Data==aDate)//若a是第一个结点
next=p;
while(p->
Data!
=aDate&
&
p->
next!
=NULL)//查找结点a
q=p;
p=p->
Data==aDate)///若有结点a
q->
next=s;
}?
else//若没有结点a;
4.链表结点的删除
如果要在链表中删除结点a并释放被删除的结点所占的存储空间,则需要考虑下列几种情况。
(1)若要删除的结点a是第一个结点,则把head指向a的下一个结点。
(2)若要删除的结点a存在于链表中,但不是第一个结点,则应使a得上一个结点a_k-1的指针域指向a的下一个结点a_k+1。
(3)空表或要删除的结点a不存在,则不做任何改变。
deletelist(intaDate)//设aDate是要删除的结点a中的数据成员
Node*p,*q;
//p用于指向结点a,q用于指向结a的前一个结点
if(p==NULL)//若是空表
return;
head=p->
deletep;
=NULL)//a既不是头结点也不是终结点,则查找结点a
Data==aDate)//若有结点a
next=p->
例题;
利用以上三个链表操作成员函数insertlist,deletelist.outputlist,可形成以下的简单链表操作
#include"
iostream.h"
voidinsertlist(intaData,intbData);
voiddeletelist(intaData);
voidoutputlist();
Node*gethead(){returnhead;
insertlist(intaData,intbData)//设aData是结点a中的数据,bData是结点b中的数据
Data=bData;
//设b为此结点
Data==aData)//若a是第一个结点
=aData&
Data==aData)///若有结点a
deletelist(intaData)//设aData是要删除的结点a中的数据成员
Data==aData)//若有结点a
voidmain()
listA,B;
intData[10]={25,41,16,98,5,67,9,55,1,121};
A.insertlist(0,Data[0]);
//建立链表A首结点
for(inti=1;
i<
10;
i++)
A.insertlist(0,Data[i]);
//顺序向后插入
\n链表A:
A.outputlist();
A.deletelist(Data[7]);
删除元素Data[7]后"
B.insertlist(0,Data[0]);
//建立链表B首结点
for(i=0;
B.insertlist(B.gethead()->
Data,Data[i]);
//在首结点处顺序向后插入
\n链表B:
B.outputlist();
B.deletelist(67);
删除元素67后"
程序运行结果为
链表A;
25,41,16,98,5,67,9,55,1,121
删除元素Data[7]后;
25,41,16,98,5,67,9,1,121
链表B;
121,1,55,9,67,5,98,16,41,25,
删除元素67后;
121,1,55,9,5,98,16,41,25,
下面是杨辉三角的代码:
#include<
iostream>
iomanip>
usingnamespacestd;
intmain()
constintn=11;
inti,j,a[n][n];
for(i=1;
n;
a[i][i]=1;
a[i][1]=1;
for(i=3;
for(j=2;
j<
=i-1;
j++)
a[i][j]=a[i-1][j-1]+a[i-1][j];
for(j=1;
=i;
setw(5)<
a[i][j]<
return0;
iostream,h>
string.h>
intnum;
Node*Create()//链表创建
intn=0;
Node*p1,*p2,*head;
p1=p2=newNode;
cin>
>
p1->
num;
head=NULL;
while(p1->
num!
=0)
if(n==1)
head=p1;
p2->
next=p1;
p2=p1;
p1=newNode;
n++;
returnhead;
intListLength(NodeL)//链表的计数
Nodep=L;
intcount=0;
next)
count++;
returncount;
intSearch(Node&
L,intvalue)//链表的查找
{
intindex=0;
while(p)
num==value)
returnindex;
index++;
voidPrint(Node*head)//输出链表
Node*p=head;
num<
voidDestruct(Node*head)//清空链表
Node*current=head,*temp=NULL;
while(current)
temp=current;
deletetemp;
Node*ReverseList(Node*head)//链表逆序(循环方法)
Node*p,*q,*r;
//一开始p指向第一个节点
q=p->
//q指向第二个节点
while(q!
=NULL)//如果没到链尾
{//以第一次循环为例
r=q->
//r暂时存储第三个节点
//没执行此句前,q->
next指向第三个节点
//执行之后,q->
next指向第一个节点p
p=q;
//之后p指向第二个节点
q=r;
//q指向第三个节点
//即...p=>
q=>
r...变为...p<
=q<
=r...
head->
//最后原来的链头变为链尾,把它指向NULL。
head=p;
//原来的链尾变成链头
Node*ReverseList2(Node*head)//链表逆序(递归方法)
if(!
head)
returnNULL;
Node*temp=ReverseList2(head->
next);
temp)
next->
next=head;
returntemp;
递归时,head可以分别用head,head1,head2...headn-1,headn来表示总共n+1个节点
temp=ReverseList2(head->
此句的递归一直将参数传进来的。
Node*head递归到headn然后判断下列语句:
elseif(!
headn->
returnheadn;
将返回值传给temp,此时temp指向链尾,由于在此次返回,故此次没有执行最后的else的那部分的语句,返回上一级即是headn-1那一级,继续执行
下面的headn-1->
next=headn-1;
headn-1->
//此两句将最后两个逆序连接,
//之后返回temp比上一层的temp即是执行temp=ReverseList2(head->
next)赋值,因为递归的口都是在这里的,如果说好理解点也可以将temp来编号
同理
在返回temp后,继续执行
headn-2->
next=headn-2;
.....
一直到head时即是原链表的第一个节点,在对其head->
next=NULL后,此时以temp所指向的节点为链头的逆序链表就形成了.
//已知两个链表head1和head2各自有序,请把它们合并成一个链表依然有序。
(循环方法)
//(保留所有结点,即便大小相同)
Node*Merge(Node*head1,Node*head2)
if(head1==NULL)
returnhead2;
if(head2==NULL)
returnhead1;
if(head1->
=head2->
num)
head=head1;
head1=head1->
head=head2;
head2=head2->
Node*temp=head;
while(head1!
=NULL&
head2!
temp->
next=head1;
temp=temp->
next=head2;
if(head1==NULL)temp->
if(head2==NULL)temp->
(递归方法)
Node*MergeRecursive(Node*head1,Node*head2)
Node*head=NULL;
head2->
next=MergeRecursive(head1->
next,head2);
next=MergeRecursive(head1,head2->
从递归函数的定义不难看出,这个函数定义中递归调用时形参发生改变,即是当前节点的下一个节点,每一次递归都按照这个规律逐次遍历两个有序链表的每一个节点,判断大小后使head指向数据域较小的节点,由堆栈空间的思想可知递归到最后指向NULL时才返回两个链表的某一个头节点,而此时head->
next=head2,head=head1链表的最后一个节点,该语句就使得这样一个指向关系确立起来。
以上均通过理想的有序链表,即链表1的任何一个数据值都小于链表2来做分析,其他的情况讨论方式类似。
Node*Delete(Node*head,intnum)//删除节点
if(head==NULL)
ListisNull"
Node*p1,*p2;
p1=head;
=num&
{?
p1=p1->
if(p1->
num==num)
if(p1==head)
head=p1->
next=p1->
DonotFindTheNum"
Node*Insert(Node*head,intnum)//插入节点
Node*p0,*p1,*p2;
p0=newNode;
p0->
num=num;
head=p0;
num&
num>
=p0->
{if(p1==head)
next=p0;
{省略不写}