我们之前讨论的是SList
单向链表,即Single List
。
这篇博客来进行DList
双向链表,即Double List
的接口实现。
双向链表的每个数据结点中都有两个指针,分别指向直接后继和直接前驱,所以它的实现相比于单链表简单了很多,但稍微繁琐了一些。
【本篇特指不带头、双向、循环链表】
定义
链表结点结构体定义:
typedef struct Node {
int value;
struct Node *next; //前驱
struct Node *prev; //后继
} Node;
初始化
void DListInit(Node **p) {
Node *node = (Node*)malloc(sizeof(Node));
// node->value 没有实际含义
node->next = node;
node->prev = node;
*p = node;
}
头插
void DListPushFront(Node *head, Node *node) {
node->next = head->next;
node->prev = head;
head->next->prev = node;
head->next = node;
}
尾插
void DListPushBack(Node *head, Node *node) {
node->next = head;
node->prev = head->prev;
head->prev->next = node;
head->prev = node;
}
结点前插入
void DListInsertAfter(Node *pos, Node *node) {
node->next = pos->next;
node->prev = pos;
pos->next->prev = node;
pos->next = node;
}
结点后插入
void DListInsertBefore(Node *pos, Node *node) {
node->next = pos;
node->prev = pos->prev;
pos->prev->next = node;
pos->prev = node;
}
- 注:
双向循环链表无论头插、尾插、头删、尾删,其时间复杂度都为O(1)
,是一种很理想、高效的数据组织方式。