zoukankan      html  css  js  c++  java
  • 链表

    一、概述

    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
  • 相关阅读:
    List<T>直接充当Combox控件DataSource并扩展自定义记录的方法
    List转Datatable 新方法
    CDM中,实体与实体快捷方式之间的联系不能重复,否则会造成外键重复
    PD中设置外键约束名称生成规则
    查询当前数据库用户会话信息
    Word中调整编号和文字的间距
    PDM/CDM中进行搜索
    PDM后续处理-驼峰规则、清除约束、外键改名
    列举当前用户或指定用户的所有表,所有字段,以及所有约束
    PDM中列举所有含取值范围、正则表达式约束的字段
  • 原文地址:https://www.cnblogs.com/a867686201/p/6090174.html
Copyright © 2011-2022 走看看