定义
链表的每个结点包含了两个指针域,一直指针域指向前面,一个指针域指向后面,称为双向链表,带有头节点就是带头双向链表。
双向链表存储结构
typedef int STDatatype;
typedef struct ListNode
{
struct ListNode* prev;//指向前一个
struct ListNode* next;//指向后一个
STDatatype data;
}LNode;
双向链表基本操作
//初始化
LNode* ListInit();
//头插
void ListPushFront(LNode* phead, STDatatype x);
//尾插
void ListPushBack(LNode* phead, STDatatype x);
//判空
bool ListEmpty(LNode* phead);
//头删
void ListPopFront(LNode* phead);
//尾删
void ListPopBack(LNode* phead);
//查找
LNode* ListFind(LNode* phead, STDatatype x);
//打印
void ListPrint(LNode* phead);
//在pos之前插入
void ListPrevInsert(LNode* pos, STDatatype x);
//在pos之后插入
void ListNextInsert(LNode* pos, STDatatype x);
//删除pos
void ListDeletePos(LNode* pos);
创建结点
LNode* BuyListNode(STDatatype x)
{
LNode* newnode = (LNode*)malloc(sizeof(LNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->data = x;
newnode->next = NULL;
newnode->next = NULL;
return newnode;
}
打印
void ListPrint(LNode* phead)
{
assert(phead);
printf("phead ");
LNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
初始化
LNode* ListInit()
{
LNode* phead = BuyListNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
头插
void ListPushFront(LNode* phead, STDatatype x)
{
assert(phead);
LNode* newnode = BuyListNode(x);
LNode* tail = phead->next;
newnode->next = tail;
tail->prev = newnode;
newnode->prev = phead;
phead->next = newnode;
}
尾插
void ListPushBack(LNode* phead, STDatatype x)
{
assert(phead);
LNode* newnode = BuyListNode(x);
LNode* cur = phead->prev;
cur->next = newnode;
newnode->prev = cur;
newnode->next = phead;
phead->prev = newnode;
}
判空
bool ListEmpty(LNode* phead)
{
assert(phead);
return phead->next == phead && phead->prev == phead;
}
头删
void ListPopFront(LNode* phead)
{
assert(phead);
assert(!ListEmpty(phead));
LNode* first = phead->next;
LNode* tail = first->next;
phead->next = tail;
tail->prev = phead;
free(first);
}
尾删
void ListPopBack(LNode* phead)
{
assert(phead);
assert(!ListEmpty(phead));
LNode* tail = phead->prev;
LNode* prev = tail->prev;
prev->next = tail->next;
phead->prev = prev;
}
查找
LNode* ListFind(LNode* phead, STDatatype x)
{
assert(phead);
LNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
在pos之前插入
void ListPrevInsert(LNode* pos, STDatatype x)
{
assert(pos);
LNode* newnode = BuyListNode(x);
LNode* prev = pos->prev;
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
在pos之后插入
void ListNextInsert(LNode* pos, STDatatype x)
{
assert(pos);
LNode* newnode = BuyListNode(x);
LNode* tail = pos->next;
tail->prev = newnode;
newnode->next = tail;
pos->next = newnode;
newnode->prev = pos;
}
删除pos
void ListDeletePos(LNode* pos)
{
assert(pos);
LNode* prev = pos->prev;
LNode* tail = pos->next;
prev->next = tail;
tail->prev = prev;
free(pos);
}
销毁
void ListDestroy(LNode** phead)
{
assert(phead);
LNode* cur = (*phead)->next;
while (cur != (*phead))
{
LNode* tail = cur->next;
free(cur);
cur = tail;
}
free(*phead);
*phead = NULL;
}
如果有不足或是错误,欢迎大神指点。