链表

一、概述

  1. 含义:链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。
  2. 特点:

    ①长度不固定,可以任意增删。
    ②存储空间不连续,数据元素之间使用指针相连,每个数据元素只能访问周围的一个元素(根据单链表还是双链表有所不同)。
    ③存储密度小,因为每个数据元素,都需要额外存储一个指向下一元素的指针(双链表则需要两个指针)。
    ④要访问特定元素,只能从链表头开始,遍历到该元素,时间复杂度为 O(n)。
    ⑤在特定的数据元素之后插入或删除元素,不涉及到其他元素的移动,因此时间复杂度为 O(1)。双链表还允许在特定的数据元素之前插入或删除元素。

  3. 与顺序表(数组)的比较 :便于插入或删除元素,但无法直接访问元素。
  4. 分类:单链表,双链表。
  5. 操作:创建,遍历,插入,删除。
  6. 习惯:
    1. head:头结点 tail:尾结点 temp:当前结点 follow: 当前结点前一结点 unit:插入结点 pointer:遍历指针
    2. create() 创建   insert()插入   del()删除

二、实现

  1. 单链表
    1. 创建 遍历 
      /*
      =======================================
      单向链表:打印1~n的数字
      创建  遍历
      =======================================
      */
      #include<iostream>
      using namespace std;
      struct student{                           //定义结构体  数据+指针 
          int grade;
          student *next;
      };
      student *create(int N)                    //创建单向链表 
      {
          student *temp,*head;
          int num=1,n=1;
          head=new student;                     //头节点 
          temp=head;
          while(n<=N){ 
              temp->grade=num;
              temp->next=new student;           //新建下一节点 
              temp=temp->next;                  //指向下一节点 
              num++;
              n++;
          }
          temp->next=NULL;
          return head;                          //返回head指针 
      }
      int main()
      {
          int n;
          cin >> n;
          student *pointer=create(n);           //创建pointer指针,指向head 
          while(pointer->next!=NULL){           //遍历,为空指针时结束 
              cout << pointer->grade << ' ';
              pointer=pointer->next;
          }
          return 0;
      }
      View Code
    2. 插入
      /*
      =======================================
      单向链表:打印1~n的数字
      插入   i在 i的前面 
      =======================================
      */
      #include<iostream>
      using namespace std;
      struct student{                           
          int grade;
          student *next;
      };
      student *create(int N)                    
      {
          student *temp,*head;
          int num=1,n=1;
          head=new student;                     
          temp=head;
          while(n<=N){ 
              temp->grade=num;
              temp->next=new student;           
              temp=temp->next;                  
              num++;
              n++;
          }
          temp->next=NULL;
          return head;                          
      }
      student *insert(student *head,int N)
      {
          student *temp,*unit,*follow;
          temp=head;
          unit=new student;
          unit->grade=N;
          unit->next=NULL;
          while( temp!=NULL && temp->grade<N ){
              follow=temp;
              temp=temp->next;
          }
          //cout << follow->grade << ' '<<temp->grade <<endl <<follow->next <<' ' << temp->next << endl;        // 测试数据  5   4/5/6/7
          if(temp->grade>N) return head;
          if(temp==head){
              unit->next=head;
              head=unit;
          }
          else{
                  follow->next=unit;
                  unit->next=temp;
          }
          return head;
      }
      int main()
      {
          int n,i;
          cin >> n >> i ;
          student *pointer=create(n);
          pointer=insert(pointer,i);
          while(pointer->next!=NULL){           
              cout << pointer->grade << ' ';
              pointer=pointer->next;
          }
          return 0;
      }
      View Code
    3. 删除
      /*
      =======================================
      单向链表:打印1~n的数字
      删除   数字i
      =======================================
      */
      #include<iostream>
      using namespace std;
      struct student{                           
          int grade;
          student *next;
      };
      student *create(int N)                    
      {
          student *temp,*head;
          int num=1,n=1;
          head=new student;                     
          temp=head;
          while(n<=N){ 
              temp->grade=num;
              temp->next=new student;           
              temp=temp->next;                  
              num++;
              n++;
          }
          temp->next=NULL;
          return head;                          
      }
      student *del(student *head,int N)
      {
          student *temp,*follow,*unit;
          temp=head;
          if(head==NULL){
              return head;
          }
          if(head->grade==N){
              head=head->next;
              delete temp;
              return head;
          }
          while(temp!=NULL&&temp->grade!=N){
              follow=temp;temp=temp->next;
          }
          if(temp!=NULL){
              follow->next=temp->next;                //不能是,follow=temp
              delete temp;
          } 
          return head;
      }
      int main()
      {
          int n,i;
          cin >> n >> i ;
          student *pointer=create(n);
          pointer=del(pointer,i);
          while(pointer->next!=NULL){           
              cout << pointer->grade << ' ';
              pointer=pointer->next;
          }
          return 0;
      }
      View Code
  2. 双链表

三、应用

6378:删除数组中的元素(链表)

总时间限制: 
1000ms
 
内存限制: 
65536kB
描述

给定N个整数,将这些整数中与M相等的删除 
假定给出的整数序列为:1,3,3,0,-3,5,6,8,3,10,22,-1,3,5,11,20,100,3,9,3 
应该将其放在一个链表中,链表长度为20 
要删除的数是3,删除以后,链表中只剩14个元素:1 0 -3 5 6 8 10 22 -1 5 11 20 100 9

要求:必须使用链表,不允许使用数组,也不允许不删除元素直接输出 
      程序中必须有链表的相关操作:建立链表,删除元素,输出删除后链表中元素,释放链表 
      不符合要求的程序即使通过,也会算作0分 

输入
输入包含3行:
第一行是一个整数n(1 <= n <= 200000),代表数组中元素的个数。
第二行包含n个整数,代表数组中的n个元素。每个整数之间用空格分隔;每个整数的取值在32位有符号整数范围以内。
第三行是一个整数k,代表待删除元素的值(k的取值也在32位有符号整数范围内)。
输出
输出只有1行:
将数组内所有待删除元素删除以后,输出数组内的剩余元素的值,每个整数之间用空格分隔。
样例输入
20
1 3 3 0 -3 5 6 8 3 10 22 -1 3 5 11 20 100 3 9 3
3
样例输出
1 0 -3 5 6 8 10 22 -1 5 11 20 100 9
#include<iostream>
using namespace std;
struct list{
    int num;
    list *next;
};
list *create(int n)
{
    int k,x=1;
    list *head,*temp;
    head=new list;
    temp=head;
    while(x<=n){
        cin >> k;
        temp->num=k;
        temp->next=new list;
        temp=temp->next;
        x++;
    }
    temp->next=NULL;
    return head;
}
list *del(list *head,int k)
{
    list *temp,*follow;
    temp=head;
    if(head==NULL) {
        return head;
    }
    while(head->num==k){
        head=head->next;
        temp=head;
    }
    while(temp->next!=NULL){
        if(temp->num!=k) {
            follow=temp;
            temp=temp->next;
        }
        else {
            follow->next=temp->next;
            temp=follow->next;
        }
    }
    return head;
}
int main()
{
    int n,k;
    cin >> n;
    list *pointer=create(n);
    cin >> k;
    pointer=del(pointer,k);
    while(pointer->next!=NULL){
        cout << pointer->num << ' ' ;
        pointer=pointer->next;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/a867686201/p/6090174.html