链表介绍
链表是由节点构成的一条链,每一个节点由两部分组成,一部分存储此节点的信息(数据域),另一部分存储链表后继元素的存储位置(指针域),这两部分合在一起就是一个节点。链表的节点通常用结构体来表示,一个表示数据域,一个表示指针域。
struct Node{
int data; //链表的数据域
Node *next; //链表的指针域(指针类型)
};
链表的定义和普通结构体变量的定义是一样的,但是链表是指针变量。
Node *p;
单向链表的基本操作
单向链表是链表的一种,单向链表是从头到尾,只可以单向查询或者寻找。每次查询或者寻找必须从链表的开头开始。下面的图可以直观的了解单向链表结构:
(一)申请、释放存储单元
p=new Node; //申请存储单元
free(s); //释放空间
(二)初始化
链表初始化为NULL,而且链表一般有一个开始的部分head,作为链表的开始,而且一般head中不存放数据,只有一个指向链表第一个元素的指针next。
(三)查找链表在x位置的元素
链表的查询是链表的基本操作之一。具体步骤:从头开始遍历整个链表,找到第x个位置的元素并输出。下面是代码:
void get(int x){ //查找第x个元素
Node *p; //申请指针变量
p=head->next; //从第一个元素开始
int i=1;
while((p!=NULL) && (i<x)){
i++;
p=p->next;
}
if(p!=NULL && i==x) printf("%d\n",p->data); //如果满足条件就输出位置
}
因为链表初始化时NULL,所以在while语句的条件中是p!=NULL。要查找第x个元素,while的条件是i<x,而不是i<=x,想想为什么?因为当满足i<x时,还会继续做,等到i=x时,while才会停止。
(四)在链表中查找元素x
在链表中寻找x,依旧要从head开始寻找,具体步骤见一下代码:
①查找元素x在链表中第一次出现的位置
②查找元素x在链表中出现的所有位置
void search1(int x){ //查找x第一次出现的位置
Node *p;
p=head->next;
int i=1;
while(p->data!=x && p->next!=NULL){
p=p->next;
i++;
}
if(p->data==x) printf("%d\n",i);
}
void search2(int x){ //查找所有x的位置
Node *p;
p=head->next;
int i=1;
while(p->next!=NULL){ //只要没有遍历整个链表,就继续寻找
if(p->data==x) printf("%d ",i);
p=p->next;
i++;
}
printf("\n");
}
(四)在元素i之前,插入x
在单向链表中插入元素理解起来还是比较简单的,因为链表的各个部分之间是用指针链接的,在插入的时候只需要修改指针的指向就可以了。下面看一下代码:
void add(int i,int x){ // 在i之前插入x
Node *p;
p=head;
int j=0;
while(j<i-1 && p!=NULL){
p=p->next;
j++;
}
if(p!=NULL){
Node *s;
s=new Node; //申请新空间
s->data=x; //让s的数据域为x
s->next=p->next; //把s接到插入前p的下一个位置
p->next=s; //把s接到p的后面
}
}
(五)删除链表中的某个元素
删除链表中的第x个元素和之前的操作一样,也是先从头开始寻找x。在找到x之后,就可以利用与在链表中插入元素类似的方法,删除一个元素。
如上图所示,删除一个元素就是把这个元素的上一部分和下一部分连接,然后释放当前元素的空间。程序如下:
void delete_1(int x){ //删除第x个元素
Node *s,*p;
p=head;
int i=0;
while(p->next!=NULL && i<x-1){
p=p->next;
i++;
}
if(p->next!=NULL){
s=p->next; //把第x个元素取出链表
p->next=p->next->next; //把p下一个的下一个接到p后面
free(s); //释放元素x的空间
}
}
(六)求一条链表的长度
求链表的长度只需要从头到尾遍历一遍链表就OK啦!非常的简单哦,就不做过多的解释了,代码如下:
void len(){ //输出链表的长度
Node *p;
p=head;
int i=0;
while(p!=NULL){
++i;
p=p->next;
}
printf("%d\n",i-1);
}
总结
单向链表的基础操作差不多就介绍完了,下面附上一个完整的单向链表基础操作代码:
#include<bits/stdc++.h>
using namespace std;
struct Node{
int data;
Node *next;
};
Node *head,*r;
int n,q,m;
void search1(int x){
Node *p;
p=head->next;
int i=1;
while(p->data!=x && p->next!=NULL){
p=p->next;
i++;
}
if(p->data==x) printf("%d\n",i);
}
void search2(int x){
Node *p;
p=head->next;
int i=1;
while(p->next!=NULL){
if(p->data==x) printf("%d ",i);
p=p->next;
i++;
}
printf("\n");
}
void get(int x){
Node *p;
p=head->next;
int i=1;
while((p!=NULL) && (i<x)){
i++;
p=p->next;
}
if(p!=NULL && i==x) printf("%d\n",p->data);
}
void add(int i,int x){
Node *p;
p=head;
int j=0;
while(j<i-1 && p!=NULL){
p=p->next;
j++;
}
if(p!=NULL){
Node *s;
s=new Node;
s->data=x;
s->next=p->next;
p->next=s;
}
}
void delete_1(int x){
Node *s,*p;
p=head;
int i=0;
while(p->next!=NULL && i<x-1){
p=p->next;
i++;
}
if(p->next!=NULL){
s=p->next;
p->next=p->next->next;
free(s);
}
}
void len(){
Node *p;
p=head;
int i=0;
while(p!=NULL){
++i;
p=p->next;
}
printf("%d\n",i-1);
}
int main(){
Node *p;
int i,j,x;
cin>>n>>m;
head=new Node;
r=head;
for(i=1;i<=n;i++){
p=new Node;
cin>>x;
p->data=x;
p->next=NULL;
r->next=p;
r=p;
}
for(i=1;i<=m;i++){
cin>>q;
if(q==1){
cin>>x;
get(x);
}
else if(q==2){
cin>>x;
search1(x);
}
else if(q==3){
cin>>x;
search2(x);
}
else if(q==4){
cin>>i>>x;
add(i,x);
}
else if(q==5){
cin>>x;
delete_1(x);
}
else if(q==6) len();
}
return 0;
}