双链表的基本操作
双链表相对于单链表来说,每一个节点还存了一个指向上一个节点的指针,提升了便捷性,例如某些情境下我们需要找到当前节点的上一个节点等问题,双链表对于单链表有很大的优势。双链表尾节点的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); }