链表知识的一些总结

线性表的链式表示

  1. 链式存储结构可以进行较快地插入和删除,并且存储结构可以反映数据之间的逻辑关系
  2. 链式存储分为:单链表、双链表、循环单链表、循环双链表和静态链表。

一、单链表

  1. 单链表的结点结构

  2. 定义:

    typedef struct LNode{
        ElemType data;
        struct LNode *next;
    }LNode,*LinkList;
    
  3. 头结点

    头结点的数据域可以不设值,也可以记录表长等信息,计算数据结点的个数时不需计算头结点

    引入头结点的好处

    • 方便运算的实现
    • 统一空表和非空表的实现
  4. 头插法创建单链表

    LinkList List_HeadInsert(LinkList &L){
        LNode *s,int x;
        L = (LinkList)malloc(sizeof(LNode));
        L->next = NULL;
        scanf("%d",&x);
        while(x!=9999){
            s = (LNode*)malloc(sizeof(LNode));
            s->data = x;
            s->next = L->next;
            L-next = s;
            scanf("%d",&x);
        }
        return L;
    }
    
  5. 头插法创建单链表

    LinkList List_TailInsert(LinkList &L){
        LNode *s,int x;
        LNode *r = L;
        L = (LinkList)malloc(sizeof(LNode));
        *r = L;
        scanf("%d",&x);
        while(x!=9999){
            s = (LNode*)malloc(sizeof(LNode));
            s->data = x;
            r->next = s;
            r = s;
            scanf("%d",&x);
        }
        r->next = NULL;
        return L;
    }
    
  6. 插入结点

    • 复杂度为O(n)

      p = GetElem(i-1);
      s->next = p->next;
      p->next = s->next;
      
    • 复杂度为O(1)

      s->next = p->next;
      p->next = s;
      ElemType temp = p->data;
      p->data = s->data;
      s->data = temp;
      
  7. 删除结点

    • 复杂度为O(n)

      p = GetElem(i-1);
      q  = p->next;
      p->next = q->next;
      free(q)
      
    • 复杂度为O(n)

      q = p->next;
      p->data = q->data;
      p->next = q->next;
      free(q);
      

二、双链表

  1. 定义

    typedef struct DNode{
        ElemType data;
        struct DNode *prior,*next;
    }DNode,*DinkList;
    

插入和删除操作的时间复杂度为O(1)

  1. 插入操作

    s->next = p->next;//把s结点插入到p结点后
    p->next-prior = s;
    p->next = s;
    s-prior = p;
    
  2. 删除操作

    p->next = q->next;//删除p结点的后继节点q
    q->next->prior = p;
    free(q);
    

三、循环单链表

  1. 循环单链表与单链表的区别在于:尾结点不指向NULL,而是指向首结点L,解r->next = L
  2. 循环单链表在任一个位置的插入和删除都是等价的,无需判断是否是表尾。
  3. 可以从任一位置遍历整个链表。
  4. 当单链表的操作经常在表头和表尾进行,采用熏坏单链表不设头指针而设尾指针,效率会更高。例如,在最后一个元素插入一个元素和删除第一个元素。注意,当链表操作要删除最后一个元素时效率并不高,与链表的长度有关系。

四、循环双链表

当链表常用的操作是在末尾插入和删除结点时,应该选用带头结点的循环双链表,例如,删除第一个元素、删除最后一个元素、在第一个元素之前插入元素、在最后一个元素之后插入新元素。

带头结点的双循环链表L为空的条件是:

L->prior = L && L->next = L

五、静态链表

  1. 静态链表借助数组来描述线性表的链式存储结构,需要提前分配一块连续的地址空间
  2. 静态链表以next==-1为结束标志
  3. 静态链表的插入、删除操作与动态链表相同,只需要修改指针,但静态链表不需要移动元素

六、顺序表和链表的比较

  1. 存取(读写)方式

    顺序表可以顺序、随机存取,链表只能顺序存取。

  2. 逻辑结构和物理结构

    采用顺序结构时,逻辑上相邻的元素物理存储位置也相同;链表则不一定,对应的逻辑关系是通过指针链接表示的。

  3. 查找、插入和删除操作

    对于按值查找,顺序表无序时,两者的时间复杂度均为O(n);顺序表有序时,可以采用折半查找。

    顺序表的插入、删除操作,平均需要移动半个表长的元素,链表只需要修改指针域即可。

    由于链表的每个结点都带有指针域,故而存储密度不大。

  4. 空间分配

    顺序存储的静态存储分配和动态存储分配都具有一定的缺点;而链表只在需要的时候申请分配,只要内存有空间就可以分配,操作高效、灵活。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值