双向链表操作
双向链表的每个结点同时保存 prev 和 next。插入或删除结点时,必须分别修复前向和后向连接。
插入结点
头部插入需要更新 head,尾部插入需要更新 tail,中间插入需要让前驱和后继都连接到新结点。
互动实验
双向链表插入
访问权限PRO
PRO EXCLUSIVE探索不止于此
尊享 Pro 权益解锁完整互动实验、进阶解析与精选参考答案。
C
singly_linked_list_t *singly_linked_list_insert(singly_linked_list_t *list, int index, T elem) {
if (list == NULL) {
return NULL;
}
if (index < 0 || index > list->size) {
fprintf(stderr, "Error: index out of bound.\n");
return list;
}
node_t *node = singly_linked_list_node_create(elem);
if (index == 0) {
node->next = list->head;
list->head = node;
if (list->tail == NULL) {
list->tail = node;
}
} else {
node_t *prev = list->head;
for (int i = 0; i < index - 1; i++) {
prev = prev->next;
}
node->next = prev->next;
prev->next = node;
if (node->next == NULL) {
list->tail = node;
}
}
list->size++;
return list;
}删除结点
删除头结点或尾结点时需要更新对应端点;删除中间结点时,需要让前驱和后继在两个方向上直接相连。
互动实验
双向链表删除
访问权限PRO
PRO EXCLUSIVE探索不止于此
尊享 Pro 权益解锁完整互动实验、进阶解析与精选参考答案。
知识测验
题目
双向链表中 A ⇄ B ⇄ C,B 是中间结点。删除 B 后,哪组更新能保持两个方向都正确连通?
C
T singly_linked_list_remove(singly_linked_list_t *list, int index) {
if (list == NULL || index < 0 || index >= list->size) {
exit(1);
}
node_t *node;
if (index == 0) {
node = list->head;
list->head = node->next;
if (list->tail == node) {
list->tail = NULL;
}
} else {
node_t *prev = list->head;
for (int i = 0; i < index - 1; i++) {
prev = prev->next;
}
node = prev->next;
prev->next = node->next;
if (list->tail == node) {
list->tail = prev;
}
}
T elem = node->data;
free(node);
list->size--;
return elem;
}