欢迎光临
我们一直在努力

[数据结构]链表Learning_0+

标题:双向循环链表

一、带头结点的双向循环链表

双向循环链表(带尾指针)核心关系梳理

1. 尾节点的直接后继。尾节点  tail  的  next  直接指向头结点 head,构成循环。 tail \\rightarrow next = head

2. 头节点的直接前驱。头结点  head  的  prev  直接指向尾节点 tail,不是空指针。 head \\rightarrow prev = tail

3. 完整闭环关系 – 尾后继: tail->next = head  – 头前驱: head->prev = tail  – 任意节点 p: p->next  后继, p->prev  前驱 – 整个链表首尾互相指向,不存在  NULL ,这是循环链表特征。

4. 带尾指针结构补充: 若链表用尾指针  tail  标识(不单独存头指针),那么头结点 =  tail->next ,访问头节点无需额外变量,头节点前驱永远是  tail 。

二、双向循环链表:带头节点 VS 不带头结点

带头节点链表 vs 不带头节点链表(单链表举例)   2.1. 定义   (1)不带头节点链表 链表第一个节点直接存有效数据,头指针  head  直接指向第一个数据节点。 结构: head → 节点1(数据) → 节点2(数据) → … → NULL  – 空链表: head = NULL 

(2)带头节点链表 链表最前面多一个无有效数据的空节点(头结点),头指针永远指向这个头结点,真正数据节点挂在头结点后面。 结构: head → 头结点(无数据) → 节点1(数据) → 节点2(数据) → … → NULL  – 空链表: head->next = NULL , head  本身不为空   2.2. 关键区别   ① 判空逻辑

– 不带头: if (head == NULL)  – 带头: if (head->next == NULL) 

② 头部插入/删除(最大优势)

不带头 在链表最前面新增节点: 要修改头指针  head ,代码需要单独处理头指针,逻辑分支多。 删除第一个节点:也要更新  head = head->next 。 带头 头结点固定不动,所有增删操作逻辑统一,不用特殊处理头部。 不管在表头、表中、表尾插入,代码写法完全一致,简化逻辑。

③ 初始化

– 不带头: LinkList head = NULL;  – 带头:先申请头结点内存  head = malloc(sizeof(Node)); head->next = NULL; 

C语言单链表

不带头节点初始化 c    typedef struct Node{     int data;     struct Node *next; }Node,*LinkList; LinkList head = NULL; // 空链表直接置空 带头节点初始化 c    LinkList head; head = (Node*)malloc(sizeof(Node)); head->next = NULL; // 头结点后继为空

三、区分普通双向链表 vs 双向循环链表

普通双向链表(不循环): – 头结点  prev = NULL  – 尾结点  next = NULL  双向循环链表:所有指针都不为空,首尾互指。

 

赞(0)
未经允许不得转载:171主机测评 » [数据结构]链表Learning_0+
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址