一、双向链表
(一)基本概念
- 核心特性:双向链表的每个节点包含两个指针(前向指针prev_p和后向指针next_p),支持双向遍历;若首尾节点相连形成双向循环链表,可进一步提升操作便捷性(如无需遍历即可定位尾节点),是实际应用中最常见的链表形态。
- 优势:相比单向链表,双向链表在删除节点(无需回溯查找前驱节点)、逆向遍历等场景下更高效。
(二)核心设计与实现
1. 节点设计
- 结构组成:包含数据域(存储具体数据)和指针域(两个指针分别指向前后节点)。
- 示例代码:
| typedef struct node { // 数据域(可替换为任意数据类型) int data; // 指针域 struct node* prev_p; // 指向前驱节点 struct node* next_p; // 指向后继节点 } node_t, *node_p; |
2. 初始化操作
- 头节点初始化:
头节点为无数据的 "哨兵节点",简化增删查改操作,初始化时prev_p和next_p均指向NULL。
| node_p DLINK_LIST_InitHeadNode(void) { node_p p = malloc(sizeof(node_t)); if (p != NULL) { p->prev_p = NULL; p->next_p = NULL; } return p; } |
- 数据节点初始化:
数据节点包含具体数据,初始化时prev_p和next_p指向NULL,数据域赋值为输入值。
| node_p DLINK_LIST_InitDataNode(int data) { node_p p = malloc(sizeof(node_t)); if (p != NULL) { p->data = data; p->prev_p = NULL; p->next_p = NULL; } return p; } |
3. 链表状态判断(为空判断)
- 判断逻辑:若头节点的prev_p和next_p均为NULL,则链表为空。
| bool DLINK_LIST_IfEmpty(node_p head_node) { return (head_node->prev_p == NULL && head_node->next_p == NULL); } |
4. 插入操作(头插法与尾插法)
- 头插法:在头节点的直接后继位置插入新节点,步骤为:
| void DLINK_LIST_HeadInsertDataNode(node_p head_node, node_p new_node) { new_node->prev_p = head_node; &n |


最低0.47元/天 解锁文章
815

被折叠的 条评论
为什么被折叠?



