最近学习链表,记录一些简单的C++链表操作。
链表是指将若干个同类型的结构体类型数据(每一个结构体类型数据成为一个节点)按一定的原则连接起来。每个节点包含两部分数据,1是描述某一实体所需要的实际数据。另一部分是结构体类型的指针,它指向下个节点,将节点连起来的原则是:前一个节点通过指针指向下一个节点。
head是链首指针,简称头指针。指向第一个节点。每个节点用new分配动态空间。
声明:
struct node
{
int info;
node *next;
};
node *head ,*p,*tail;
1向后建立链表
下面以建立学生情况(仅含学号)的链表为例说明如何用向后生成链表的算法生成链表。
node *creatdown()
{
node *head ,*tail,*p;
int n = 0,data; //n代表节点个数
head = NULL; //空链表
cin>>data;
while (data !=0) //学号不为0
{
n++;
if (n ==1) //建立链表头节点
{
head = new node;
tail = head;
head->info = data;
}
else
{
p = new node; //每输入一个数申请一个节点
p->info = data; //添加数据
tail->next = p; //新节点添加到链尾
tail = p; //尾指针到新的链尾
}
cin>>data;
}
tail->next =NULL; //链尾next赋为空指针表示链结束
return head;
}
2遍历链表
遍历链表就是将链表中各节点的数据依次输出。首先要知道head,然后通过各节点next的值找到下一个节点
void display(node *head)
{
node *q = head; //q指向head的地址。也就是q里面是head的地址。
while(q!=NULL)
{
cout<<setw(3)<<q->info;
q = q->next;
}
cout<<endl;
}
3.链表的查找
与遍历相似
node *traversal(node *head,int datafind)
{
node *p= head;
while(p!=NULL && p->info !=datafind)
p = p->next;
return p; //p为NULL则未找到
}
4.插入节点
链表便于实现插入和删除节点的动态操作,关键是正确修改节点的指针。首先要确定插入节点的操作位置,然后,按位置不同分别处理。
(1)在表头插入节点
newnode = new node; //生成新节点
newnodw ->next = head; //newnode节点的next指针指向头节点
head = newnode;
下面以建立学生情况(仅含学号)的链表为例,说明向前生成链表算法建立链表。
node *createup()
{
node *head ,*p;
int data;
cin>>data;
head = NULL;
while(data != 0)
{
p = new node; //每输入一个数申请一个节点
p->info = data;
p->next = head;
head =p; //头节点指向新节点
cin>>data;
}
return head;
}
(2)在p节点之前插入newnode节点
需要找到pjiedian 的前驱节点的地址,所以查找过程要定位p的前驱。
如果p节点已经定位,它的前驱是q节点。可以先把newnode的节点next指针指向p,然后前驱q节点的next指针指向newnode。
newnode ->next;
q->next = newnode;
(3)在链尾节点之后添加节点
假如p指向链尾节点:
newnode = new node;
newnode->info = data;
p->next = newnode;
newnode->next = NULL;
例:在头指针head的学生链表中,在学号数据值等于key的节点之前插入学号数据值等于的insertkey的节点,并返回指针。
node *insert(int key,int insertkey,node *head)
{
bool flag = false;
if(head->info ==key) //在链首插入节点newnode
{
node *newnode =new node;
newnode->info = insertkey;
newnode->next = head; //newnode节点的next指针指向头节点
head = newnode;
flag = true; //插入节点成功
return head ;
}
node *q = head;
for(node *p=head->next;p! =NULL;p = p->next) //在链表中间插入新节点
if(p->info ==key)
{
node *newnode = new node;
newnode->info = insertkey;
newnode->next = p;
q->next = newnode;
flag = true; //插入节点成功
return head;
}
}
4.删除节点
(1)删除表头节点
node *p = head ;
head = p->next;
delete p;
(2)删除链表中间的节点p,需要知道其前驱节点指针q
q->next = p->next;
delete p;
例:从头指针head的学生链表中删除节点学号数据等于key的节点,并返回头指针。
node *Delete(int key,node *head)
{
bool flag = false;
node *p = head,*q;
if(head->info ==key)
{
head = p->next;
delete p;
flag = true;
return head;
}
for(q = head;q->next!=NULL;q=q->next;)
if(q->info == key)
{
p = q->next;
q->next = p->next;
delete p;
flag =true;
return head;
}
cout<<"没有要删除的节点,删除失败";
return head;
}