链表介绍

       链表是由节点构成的一条链,每一个节点由两部分组成,一部分存储此节点的信息(数据域),另一部分存储链表后继元素的存储位置(指针域),这两部分合在一起就是一个节点。链表的节点通常用结构体来表示,一个表示数据域,一个表示指针域。

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;
}