带头双向循环链表的实现
带头双向循环链表的物理结构:
C语言实现
DList.h文件
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
typedef int DLTDataType;
typedef struct DListNode // 循环链表节点
{
DLTDataType _data;
struct DListNode* _next;
struct DListNode* _prev;
}DListNode;
typedef struct DList // 带头循环链表
{
DListNode* _head;
}DList;
void DListInit(DList* dlist); // 循环链表的初始化
void DListDestroy(DList* dlist); // 循环链表的销毁
DListNode* Buynewnode(DLTDataType x); // 创建新节点
void DListPushBack(DList* dlist, DLTDataType x); // 尾插
void DListPushFront(DList* dlist, DLTDataType x); // 前删
void DListPopBack(DList* dlist); // 尾删
void DListPopFront(DList* dlist); // 前删
void DListErase(DList* dlist, DLTDataType x); // 删除节点值为x的节点
DListNode* DListFind(DList* dlist, DLTDataType x); // 找到链表中值为x的节点
void DListInsert(DListNode* pos, DLTDataType x); // 在pos的前面插入节点
void DListErase(DListNode* pos); // 删除pos位置的节点
void DListPrint(DList* dlist);
DList.c文件
#include "DList.h"
DListNode* Buynewnode(DLTDataType x)
{
DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
newnode->_next = NULL;
newnode->_prev = NULL;
newnode->_data = x;
return newnode;
}
void DListInit(DList* dlist)
{
assert(dlist);
dlist->_head = Buynewnode(0); //头结点
dlist->_head->_next = dlist->_head;
dlist->_head->_prev = dlist->_head;
}
void DListDestroy(DList* dlist)
{
if (dlist->_head != NULL)
{
DListNode* cur = dlist->_head->_next;
while (cur != dlist->_head)
{
DListNode* next = cur->_next;
cur->_prev = NULL;
free(cur);
cur = next;
}
free(dlist->_head);
dlist->_head = NULL;
}
}
void DListPushBack(DList* dlist, DLTDataType x) //尾插
{
assert(dlist);
DListNode* newnode = Buynewnode(x);
DListNode* tail = dlist->_head->_prev;
DListNode* head = dlist->_head->_next;
tail->_next = newnode;
dlist->_head->_prev = newnode;
newnode->_prev = tail;
newnode->_next = dlist->_head;
}
void DListPushFront(DList* dlist, DLTDataType x) // 前插
{
assert(dlist);
DListNode* newnode = Buynewnode(x);
newnode->_next = dlist->_head->_next;
newnode->_prev = dlist->_head;
dlist->_head->_next->_prev = newnode;
dlist->_head->_next = newnode;
}
void DListPopBack(DList* dlist)
{
assert(dlist);
if (dlist->_head == NULL)
return;
else
{
DListNode* tail = dlist->_head->_prev;
DListNode* tmpnode = tail; // 保存尾节点,到时候释放尾节点
dlist->_head->_prev = tail->_prev;
tail->_prev->_next = dlist->_head;
tmpnode->_prev = NULL;
tmpnode->_next = NULL;
free(tmpnode);
tmpnode = NULL;
}
}
void DListPopFront(DList* dlist) //前删
{
assert(dlist);
if (dlist->_head == NULL)
return;
else
{
DListNode* Delnode = dlist->_head->_next;
// _head Delnode(第一个节点) node(后面的节点)
dlist->_head->_next = Delnode->_next;
Delnode->_next->_prev = Delnode->_prev;
Delnode->_prev = NULL;
Delnode->_next = NULL;
free(Delnode);
Delnode = NULL;
}
}
void DListErase(DList* dlist, DLTDataType x) // 删除节点值为x的节点
{
assert(dlist);
DListNode* cur = dlist->_head->_next;
while (cur)
{
if (cur->_data == x)
{
cur->_next->_prev = cur->_prev;
cur->_prev->_next = cur->_next;
cur->_next = NULL;
cur->_prev = NULL;
free(cur);
break;
}
cur = cur->_next;
}
}
DListNode* DListFind(DList* dlist, DLTDataType x) // 找到链表中值为x的节点
{
assert(dlist);
DListNode* cur = dlist->_head->_next;
while (cur != dlist->_head)
{
if (cur->_data == x)
return cur;
cur = cur->_next;
}
return NULL;
}
void DListInsert(DListNode* pos, DLTDataType x) // 在pos的前面插入节点
{
assert(pos);
DListNode* newnode = Buynewnode(x);
pos->_next = newnode;
newnode->_prev = pos->_prev;
newnode->_next = pos;
pos->_prev = newnode;
}
void DListErase(DListNode* pos) // 删除pos位置的节点
{
assert(pos);
pos->_prev = pos->_next;
pos->_next->_prev = pos->_prev;
pos->_next = NULL;
pos->_prev = NULL;
free(pos);
pos = NULL;
}
void DListPrint(DList* dlist)
{
assert(dlist && dlist->_head);
DListNode* cur = dlist->_head->_next;
while (cur != dlist->_head)
{
printf("%d ", cur->_data);
cur = cur->_next;
}
printf("\n");
}