双链表的基本操作
双链表相对于单链表来说,每一个节点还存了一个指向上一个节点的指针,提升了便捷性,例如某些情境下我们需要找到当前节点的上一个节点等问题,双链表对于单链表有很大的优势。双链表尾节点的prev指针指向头节点,故双链表的头节点为哨兵卫,不存数据,仅作为标记作用。当单链表为空时,仅存在一个头节点,next指针与prev指针均指向自己。故双链表不可能为空。
以下将给出双链表的实现代码。
typedef struct DListNode
{
struct DListNode* _next;
struct DListNode* _prev;
DataType _data;
}DListNode;
创建一个双链表的节点
DListNode* BuyDListNode(DataType x)
{
DListNode* str;
str = (DListNode*)malloc(sizeof(DListNode));
str->_data = x;
str->_next = NULL;
str->_prev = NULL;
return str;
}
链表初始化
DListNode* DListInit()
{
DListNode* head;
head = (DListNode*)malloc(sizeof(DListNode));
head->_next = head;
head->_prev = head;
return head;
}
销毁链表
void DListDestory(DListNode** head)
{
assert(head);
DListNode* ptr;
ptr = *head;
(*head)->_prev->_next = NULL;
while (ptr->_next)
{
ptr = ptr->_next;
free(ptr->_prev);
ptr->_prev = NULL;
}
}
打印链表
void DListPrint(DListNode* head)
{
assert(head);
DListNode* str;
str = head->_next;
while (str != head)
{
printf("%d ", str->_data);
str = str->_next;
}
}
尾插
void DListPushBack(DListNode* head, DataType x)
{
DListNode* str,*tail;
str = BuyDListNode(x);
tail = head->_prev;
str->_next = head;
str->_prev = tail;
head->_prev = str;
tail->_next = str;
}
尾删
void DListPopBack(DListNode* head)
{
DListNode* pos;
pos = head->_prev;
pos->_prev->_next = head;
head->_prev = pos->_prev;
free(pos);
pos->_next = NULL;
pos->_prev = NULL;
pos = NULL;
}
头插
void DListPushFront(DListNode* head, DataType x)
{
DListNode* _new,*next;
_new = BuyDListNode(x);
next = head->_next;
_new->_next = next;
_new->_prev = head;
next->_prev = _new;
head->_next = _new;
}
头删
void DListPopFront(DListNode* head)
{
DListNode* next,*first;
first = head->_next;
next = first->_next;
next->_prev = head;
head->_next = next;
free(first);
first->_next = NULL;
first->_prev = NULL;
first = NULL;
}
查找
DListNode* DListFind(DListNode* head, DataType x)
{
DListNode* str,*pos;
str = head;
while (str->_data != x)
{
str = str->_next;
}
pos = str;
return pos;
}
pos位置插入
void DListInsert(DListNode* pos, DataType x)
{
DListNode* str;
str = BuyDListNode(x);
str->_next = pos;
str->_prev = pos->_prev;
pos->_prev->_next = str;
pos->_prev = str;
}
pos位置删除
void DListErase(DListNode* pos)
{
pos->_prev->_next = pos->_next;
pos->_next->_prev = pos->_prev;
free(pos);
}