双向链表概念与结构
双向链表是一种链式存储的数据结构,每个节点包含两个指针:一个指向前驱节点(prev),一个指向后继节点(next),同时包含数据域(data)存储数据。这种结构允许双向遍历(从头到尾或从尾到头),并支持更灵活的插入、删除操作,但相比单链表会增加一定的空间开销。
我们这里采用的是带头双向循环链表。它兼具'头节点''双向指针''循环结构'三大特性,是应用最广泛的双向链表类型。其结构稳定、边界处理简单,支持高效的插入、删除和双向遍历操作。
关于头节点
带头链表中的头节点不存储有效数据,只用来简化边界操作(如插入/删除首节点时无需特殊判断)。在单链表学习中有时会把第一个节点表述为头节点,其实严谨定义下,头节点是链表中第一个节点但不存储有效数据,核心价值是简化边界操作。
双向链表结构定义
根据单向链表的知识,我们可以扩展出双向链表的结构:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int type;
typedef struct ListNode {
type data; // 数据域
struct ListNode* prev; // 前驱指针
struct ListNode* next; // 后继指针
} ListNode;
实现双向链表
1. 初始化
我们在双向链表中头节点(哨兵位)是需要初始化的。数据域可以存任意值,前驱指针和后继指针都指向自己即可,形成空循环状态。
void LTInit(ListNode** h) {
ListNode* ph = (ListNode*)malloc(sizeof(ListNode));
if (ph == NULL) {
perror("malloc fail!");
exit(1);
}
*h = ph;
(*h)->data = ;
(*h)->next = *h;
(*h)->prev = *h;
}


