知识点速览
双链表的实现
本文复习最复杂的链表结构——带头双向循环链表。其特点包括一个哨兵节点作为头节点,以及逻辑上的循环双向结构。
较单链表相比,每个节点多了一个指针指向其前一个节点,从而实现双向遍历。哨兵节点一般不存储数据,用于简化插入删除操作,无需处理二级指针,所有操作逻辑统一,减少空指针异常风险。
循环结构定义:头节点的 prev 指向尾节点,尾节点的 next 指向头节点。
节点结构
节点包含数据域、前指针域和后指针域。使用 typedef 重定义数据类型便于维护。
typedef int Plastic;
typedef struct DoubleList {
// 数据域
Plastic data;
// 前指针域
struct DoubleList* prev;
// 后指针域
struct DoubleList* next;
}DoubleList;
设置哨兵节点
哨兵节点的数据域通常不存储数据,但需单独开辟空间。初始化时头指针指向哨兵节点,哨兵节点的前后指针应指向自己,形成双向循环。
// 设置哨兵节点
DoubleList* Sentry() {
// 开辟节点
DoubleList* newnode = (DoubleList*)malloc(sizeof(DoubleList));
// 判断空间有效性
if (newnode == NULL) {
printf("哨兵节点开辟失败\n");
return NULL;
}
// 初始化
newnode->next = newnode;
newnode->prev = newnode;
return newnode;
}
开辟节点
开辟新节点与单链表类似,传入数据即可。初始化时新节点前后指针应指向自己。
// 新增节点
DoubleList* Newnode(Plastic data) {
// 开辟节点
DoubleList* newnode = (DoubleList*)((DoubleList));
(newnode == ) {
();
;
}
newnode->next = newnode;
newnode->prev = newnode;
newnode->data = data;
newnode;
}


