1
0
mirror of https://github.com/142vip/408CSFamily.git synced 2026-04-04 02:58:30 +08:00
Files
408CSFamily/docs/DataStructure/linear_table/4.double_linked_list.md
mmdapl 42117a0dd9 init
2022-04-08 00:10:38 +08:00

1.8 KiB
Raw Blame History

双链表

从单链表的结构上来看

  • 访问特定结点的前驱结点需要遍历整个单链表移动指针时间复杂度为O(n)
  • 访问特定结点的后继结点只需要移动一次指针时间复杂度为O(1)

双链表的引入,很好的解决单链表访问前驱结点时间消耗大的问题。

双链表结点由三部分组成:

  • 数据域 存放数据信息
  • prior指针域 指向结点的前驱结点
  • next指针域 指向结点的后继结点

// 双链表结点类型
typedef struct DNode{
    ElemType data;          // 结点的数据域
    struct DNode *prior;    // 结点的前驱指针
    struct DNode *next;     // 结点的后继指针
}DNode, *DlinkList;

基本特点

  • 双链表仅仅在单链表的结点中增加了一个指向结点前驱的prior指针;
  • 按值查找按序号查找在单链表和双链表上的操作是相同的。
  • 和单链表不同,插入删除操作除了修改next指针域,双链表还需要修改prior指针域,确保不断时间复杂度都为O(1)

插入结点

在双链表中p所指的结点之后插入结点s


// 第一步
s->next=p->next;

// 第二步
p->next->prior=s;

// 第三步
s->prior=p;

// 第四步
p->next=s

第一步和第二步必须再第四步之前整体时间复杂度为O(1)

删除结点

删除双链表中结点p的后继结点q


// 第一步
p->next=q->next;

// 第二步
q->next->prior=p;

// 第三步
free(q);

第一步和第二步顺序可换整体时间复杂度为O(1)