zoukankan      html  css  js  c++  java
  • 链表

    1、链表思想:每个节点都存储分为数据和地址两个方面。

    数据是链表记录的内容,地址分为此节点的地址和它的前驱和后缀地址。

    通过,每次通过地址来时先链表的遍历,查找,删除等操作。

    2、链表分类

    如果是单链表,就是只有后继,只能向后移动,因此,为了方便查找链表的某个节点,常常设置头结点。

    双向链表:同时具有前驱和后缀,可以向前或者向后移动。

    循环链表:最后的单元反过来,直至第一个单元,可以有表头,也可以是双向链表

    3、链表的具体实现操作:

    (1)单链表的实现

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<stdlib.h>
    
    #define ERRROR -1
    
    //链表的结构 
    typedef int ElementType;
    struct Node{
        ElementType x;
        struct Node *next;
    };
    typedef struct Node* List;
    typedef List Position;
    
    //链表的操作
    List MakeEmpty(List L);
    int IsEmpty(List L);
    int IsLast(Position p,List L);
    Position Find(ElementType x,List L);
    void Delete(ElementType x,List L);
    Position FindPrevious(ElementType x,List L);
    void Insert(ElementType x,List L,Position p);
    void DeleteList(List L);
    
    
    //测试是否为空表
    int IsEmpty(List L)
    {
        return L->next==NULL;
    }
    
    //测试是否为最后一个节点 
    int IsLast(Position p,List L)
    {
        return p->next==NULL;
    }
    
    //初始化
    List Init(List L)
    {
        L = (List)malloc(sizeof(struct Node));
        if(L==NULL)
        {
            printf("Out of Space!
    ");
        }
        else L->next=NULL;
        return L;
    }
     
    //查找函数 
    Position Find(ElementType x,List L)
    {
        List p=L;
        while(p!=NULL&&p->x!=x)
        {
            p=p->next;
        }
        return p;
    } 
    
    //删除链表 
    void Delete(ElementType x,List L)
    {
        List tp,p;
        p=FindPrevious(x,L);
        if(!IsLast(p,L))
        {
            tp=p->next;
            p->next=tp->next;
            free(tp);
        }
    }
    
    //查找前一个元素 
    Position FindPrevious(ElementType x,List L)
    {
        Position p=L;
        while(p->next!=NULL&&p->next->x!=x)
        {
            p=p->next;
        }
        return p;
    }
    
    //插入
    void Insert(ElementType x,List L,Position p)
    {
        List tp;
        tp=(List)malloc(sizeof(struct Node));
        if(tp==NULL)
        {
            printf("Out of Space!!!
    ");
        }
        tp->x=x;
        tp->next=p->next;
        p->next=tp; 
    } 
    
    //删除
    void DeleteList(List L)
    {
        List p,tp;
        tp=L->next;
        L->next=NULL;
        while(tp!=NULL)
        {
            p=tp->next;
            free(tp);
            tp=p;
        }
    }
    
    void Print(List L)
    {
        List p=L->next;
        while(p!=NULL)
        {
            printf("%d ",p->x);
            p=p->next;
        }
        printf("
    ");
    }
    
    int main(void)
    {
        List L,p;
        L=Init(L);
        p=L;
        int i,x,n;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(x,L,p);
            p=p->next;
        }
        Print(L);
        
        printf("将7插入3的前面:
    ");
        p=FindPrevious(3,L);
        Insert(7,L,p);
        Print(L);
        
        printf("删除4:
    ");
        Delete(4,L);
        Print(L);
        
        return 0;
    }
    View Code

    (2)双向链表

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct Node{
        int data;
        struct Node *Pre,*Rear;
    };
    typedef struct Node* DoList;
    
    DoList Init(DoList L) //初始化 
    {
        L=(DoList)malloc(sizeof(struct Node));
        L->Pre=NULL;
        L->Rear=NULL;
        return L;
    }
    
    int IsEmpty(DoList L) //判断是否为空 
    {
        if(L->Pre==NULL&&L->Rear==NULL) return 1;
        return 0;
    }
    
    int IsLast(DoList L,DoList p) //判断最后一个元素 
    {
        if(p->Pre!=NULL&&p->Rear==NULL) return 1;
        return 0;
    }
    
    DoList FindPrevious(int x,DoList L) //找到前一个元素 
    {
        DoList p=L;
        while(p->Rear!=NULL&&p->Rear->data!=x)
        {
            p=p->Rear;
        }
        return p;
    }
    
    void Insert(int x,DoList L,DoList p) //插入某个元素 
    {
        DoList tp=(DoList)malloc(sizeof(struct Node));
        if(tp==NULL)
        {
            printf("Out of Space!!!
    ");
        }
        //printf("%d
    ",x);
        tp->data=x;
        //先前再后
        tp->Pre=p;
        tp->Rear=p->Rear;  
        if(p->Rear==NULL) p->Rear=tp; //这里要注意,因为可能存在p->Rear==NULL的情况。 
        else
        {
            p->Rear->Pre=tp;
            p->Rear=tp;
        }
    }
    
    void Delete(int x,DoList L) //删除某个元素 
    {
        DoList p,tp;
        p=FindPrevious(x,L);
        tp=p->Rear;
        p->Rear=tp->Rear;
        tp->Rear->Pre=p;
        free(tp);
    }
    
    void Print(DoList L) //正序输出 
    {
        DoList p=L->Rear;
        while(p!=NULL)
        {
            printf("%d ",p->data);
            p=p->Rear;
        }
        printf("
    ");
    }
    
    void RePrint(DoList L) //逆序输出
    {
        DoList p,tp;
        p=L->Rear;
        while(!IsLast(L,p)) p=p->Rear;
        while(p->Pre!=NULL)
        {
            printf("%d ",p->data);
            p=p->Pre;
        }
        printf("
    ");
    }
    
    void DeleteList(DoList L) //输出链表 
    {
        DoList p,tp;
        p=L->Rear;
        L->Rear=NULL;
        while(p!=NULL)
        {
            tp=p->Rear;
            free(p);
            p=tp;
        }
    }
    
    int main(void)
    {
        DoList L,p;
        L=Init(L);
        p=L;
        int n,x,i;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(x,L,p);
            p=p->Rear;
        }
        Print(L);
        
        p=FindPrevious(3,L);
        Insert(7,L,p);
        //DeleteList(L); 
        RePrint(L);
        return 0;
    }
    View Code

    (3)循环链表

    循环单链表

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct Node{
        int data;
        struct Node *next;
    }; 
    typedef struct Node* CyList;
    
    CyList Init(CyList L)
    {
        L=(CyList)malloc(sizeof(struct Node));
        L->data=-1;
        L->next=L;
        return L;
    }
    
    int Empty(CyList L)
    {
        return L->next==L;
    }
    
    CyList FindPrevious(int x,CyList L)
    {
        CyList p=L;
        while(p->next->data!=x&&p->next!=NULL)
        {
            p=p->next;
        }
        return p;
    }
    
    void Insert(int x,CyList L,CyList p)
    {
        CyList tp=(CyList)malloc(sizeof(struct Node));
        tp->data=x;
        tp->next=p->next;
        p->next=tp;
    }
    
    void Delete(int x,CyList L)
    {
        CyList p,tp;
        p=FindPrevious(x,L);
        if(p->next!=NULL)
        {
            tp=p->next;
            p->next=tp->next;
            delete tp;
        }
    }
    
    void Print(CyList L)
    {
        CyList p=L->next;
        while(p!=L)
        {
            printf("%d ",p->data);
            p=p->next;
        } 
        printf("
    ");
    }
    
    void DeleteList(CyList L)
    {
        CyList p,tp;
        p=L->next;
        L->next=L;
        while(p!=L)
        {
            tp=p->next;
            delete p;
            p=tp;
        }
    }
    
    void DoPrint(CyList L)
    {
        CyList p=L->next;
        int tim=0;
        while(1)
        {
            if(tim==1&&p==L) break;
            if(p==L&&tim==0)
            {
                p=p->next;
                tim=1;continue;
            }
            printf("%d ",p->data);
            p=p->next;
        }
    }
    
    int main(void)
    {
        CyList L,p;
        L=Init(L);
        p=L;
        int n,i,x;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(x,L,p);
            p=p->next;
        }
        p->next=L;
        Print(L);
        
        p=FindPrevious(3,L);
        Insert(7,L,p);
        Print(L);
        
        Delete(2,L);
        Print(L);
        
        DoPrint(L);
        return 0;
    }
    View Code

    循环双向链表

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    struct Node{
        int data;
        struct Node *Pre,*Rear;
    };
    typedef struct Node* DuList;
    
    DuList Init(DuList L)
    {
        L=(DuList)malloc(sizeof(struct Node));
        L->Pre=L;
        L->Rear=L;
        return L;
    }
    
    int IsEmpty(DuList L)
    {
        if(L->Pre==L&&L->Rear==L) return true;
        return false;
    }
    
    void Insert(int x,DuList L,DuList p)
    {
        DuList tp=(DuList)malloc(sizeof(struct Node));
        tp->data=x;
        tp->Pre=p;
        tp->Rear=p->Rear;
        p->Rear->Pre=tp;
        p->Rear=tp;
    }
    
    DuList FindPrevious(int x,DuList L)
    {
        DuList p=L;
        while(p->data!=x) p=p->Rear;
        return p->Pre;
    }
    
    void Delete(int x,DuList L)
    {
        DuList p,tp;
        p=FindPrevious(x,L);
        tp=p->Rear;
        p->Rear=tp->Rear;
        tp->Rear->Pre=p;
    }
    
    void Print(DuList L)
    {
        DuList p=L;
        printf("%d ",p->data);
        p=p->Rear;
        while(p!=L)
        {
            printf("%d ",p->data);
            p=p->Rear;
        }
        printf("
    ");
    }
    
    void DeleteList(DuList L)
    {
        DuList p=L->Rear,tp=L;
        delete tp;
        L=NULL;
        while(p!=NULL)
        {
            tp=p->Rear;
            delete tp;
            p=tp;
        }
    }
    
    int main(void)
    {
        int n,x,i;
        DuList p,L;
        scanf("%d",&n);
        scanf("%d",&x);
        p=Init(p);
        p->data=x;
        L=p;
        for(i=1;i<n;i++)
        {
            scanf("%d",&x);
            Insert(x,L,p);
            p=p->Rear;
        }
        Print(L);
        
        Delete(3,L);
        Print(L);
        
        p=FindPrevious(2,L);
        Insert(7,L,p);
        Print(L);
        
        return 0; 
    }
    View Code

    注意:1、如果对p->next进行操作,p一定不能为空,否则会出问题。

    2、双向链表中的插入操作,先对tp的前驱操作,再对tp的后驱操作。

    3、循环链表的最大特征就是首尾相连,空表时,自己指向自己(指的是单链表的头结点,如果是双向链表,直接让第一个节点的前驱指向最后一个节点,

    最后一个节点的后驱指向第一个节点就行了)。

    书后练习:

    3.2:

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<time.h>
    
    struct Node{
        int id,data;
        struct Node* next;
    };
    typedef struct Node* List;
    
    List Init(List L)
    {
        L=(List)malloc(sizeof(struct Node));
        L->next=NULL;
        return L;
    }
    
    void Insert(int x,List L,List p)
    {
        List tp=(List)malloc(sizeof(struct Node));
        tp->data=x;
        if(tp==NULL)
        {
            printf("Out of Space!!!
    ");
        }
        tp->next=p->next;
        p->next=tp;
    }
    
    int FindNum(List L,int pos)
    {
        List tp,p=L->next;
        int i=1;
        while(p!=NULL&&i!=pos)
        {
            i++;p=p->next;
        }
        return p->data;
    }
    
    void PrintLots(List L,List p)
    {
        List tp=p->next;
        while(tp!=NULL)
        {
            printf("%d ",FindNum(L,tp->data));
            tp=tp->next;
        }
        printf("
    ");
    }
    
    void Print(List L)
    {
        List p=L->next;
        while(p!=NULL)
        {
            printf("%d ",p->data);
            p=p->next;
        }
        printf("
    ");
    }
    
    int main(void)
    {
        int begintime=0,endtime;
        List L1,p,L2;
        L1=Init(L1);
        L2=Init(L2);
        p=L1;
        int n,x,i;
        printf("创建L序列:
    ");
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(x,L1,p);
            p=p->next;
        }
        Print(L1);
        
        printf("创建P序列:
    ");
        p=L2;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&x);
            Insert(x,L2,p);
            p=p->next;
        }
        Print(L2);
        
        PrintLots(L1,L2);
        endtime=clock();
        printf("程序运行时间为:%dmm
    ",endtime-begintime);
        return 0;
    }
    View Code
  • 相关阅读:
    Do You See Me? Ethical Considerations of the Homeless
    ELDER HOMELESSNESS WHY IS THIS AN ISSUE?
    Endoflife support is lacking for homeless people
    html内联框架
    html字体
    html块 div span
    html列表
    html表格
    SQL Server管理员专用连接的使用   作为一名DBA,经常会处理一些比较棘手的服务无响应问题,鉴于事态的严重性,多数DBA可能直接用“重启”大法,以便尽快的恢复生产环境的正常运转,但是多数情况
    如何配置最大工作线程数 (SQL Server Management Studio)
  • 原文地址:https://www.cnblogs.com/2018zxy/p/10017542.html
Copyright © 2011-2022 走看看