实现双向带头循环链表的各个接口
双向带头循环链表
双向带头循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是双向带头循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,具体看后面的代码实现了就知道了。
List.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int LTDateType;
typedef struct ListNode
{
LTDateType _date;
struct ListNode* _next;
struct ListNode* _prev;
}ListNode;
//双向带头循环链表
typedef struct List
{
ListNode* _head;
}List;
void ListInit(List* plist);
void ListDestory(List* plist);
ListNode* BuyListNode(LTDateType x);
void ListPushBack(List* plist, LTDateType x);
void ListPopBack(List* plist);
void ListPushFront(List* plist, LTDateType x);
void ListPopFront(List* plist);
void ListInsert(ListNode* pos, LTDateType x);//在pos前面插入
void ListErase(ListNode* pos);
ListNode* ListFind(List* plist,LTDateType x);
void ListPrint(List* plist);
void TestList();
List.c
#include "List.h"
void ListInit(List* plist)//初始化
{
assert(plist);
plist->_head = BuyListNode(0);
plist->_head->_next = plist->_head;
plist->_head->_prev = plist->_head;
}
void ListDestory(List* plist)//销毁
{
assert(plist);
ListNode* cur = plist->_head->_next;
while (cur != plist->_head)
{
ListNode* next = cur->_next;
free(cur);
cur = next;
}
free(plist->_head);
plist->_head = NULL;
}
ListNode* BuyListNode(LTDateType x)//开辟一个节点
{
ListNode* newnode = malloc(sizeof(ListNode));
assert(newnode);
newnode->_date = x;
newnode->_next = NULL;
newnode->_prev = NULL;
return newnode;
}
void ListPushBack(List* plist, LTDateType x)//尾插
{
assert(plist);
//ListNode* head = plist->_head;
//ListNode* tail = plist->_head->_prev;
//ListNode* newnode = BuyListNode(x);
//tail->_next = newnode;
//newnode->_prev = tail;
//newnode->_next = head;
//head->_prev = newnode;
//也可以写成以下代码
//(因为是循环链表结构,所以头的前面就是尾)
ListInsert(plist->_head, x);
}
void ListPopBack(List* plist)//尾删
{
assert(plist);
//ListNode* head = plist->_head;
//ListNode* tail = head->_prev;
//ListNode* prev = tail->_prev;
//head->_prev = prev;
//prev->_next = head;
//free(tail);
//tail = NULL;
//也可以写成以下代码
ListErase(plist->_head->_prev);
}
void ListPushFront(List* plist, LTDateType x)//头插
{
assert(plist);
//ListNode* newnode = BuyListNode(x);
//ListNode* head = plist->_head;
//ListNode* next = head->_next;
//head->_next = newnode;
//newnode->_prev = head;
//newnode->_next = next;
//next->_prev = newnode;
//也可以写成以下代码
ListInsert(plist->_head->_next, x);
}
void ListPopFront(List* plist)//头删
{
assert(plist);
//ListNode* head = plist->_head;
//ListNode* next = head->_next;
//ListNode* nextnext = next->_next;
//if (head == next)
// return;
//head->_next = nextnext;
//nextnext->_prev = head;
//free(next);
//next = NULL;
//也可以写成以下代码
ListErase(plist->_head->_next);
}
void ListPrint(List* plist)//打印
{
assert(plist);
ListNode* cur = plist->_head->_next;
while (cur != plist->_head)
{
printf("<- %d -> ", cur->_date);
cur = cur->_next;
}
printf("\n");
}
void ListInsert(ListNode* pos, LTDateType x)//pos位置前面插入
{
assert(pos);
ListNode* prev = pos->_prev;
ListNode* newnode = BuyListNode(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = pos;
pos->_prev = newnode;
}
void ListErase(ListNode* pos)//删除pos这个节点
{
assert(pos);
ListNode* prev = pos->_prev;
ListNode* next = pos->_next;
prev->_next = next;
next->_prev = prev;
free(pos);
pos = NULL;
}
ListNode* ListFind(List* plist, LTDateType x)//查找一个节点
{
assert(plist);
ListNode* cur = plist->_head->_next;
while (cur != plist->_head)
{
if (cur->_date == x)
{
return cur;
}
else
{
cur = cur->_next;
}
}
return NULL;
}
void TestList()//测试函数
{
List lt;
ListInit(<);
ListPushBack(<, 1);
ListPushBack(<, 2);
ListPushBack(<, 3);
ListPushBack(<, 4);
ListPrint(<);
ListPopBack(<);
ListPopBack(<);
ListPrint(<);
ListPushFront(<, 30);
ListPushFront(<, 40);
ListPrint(<);
ListPopFront(<);
ListPopFront(<);
ListPrint(<);
ListNode* pos = ListFind(<,2);
ListInsert(pos, 100);
ListPrint(<);
ListErase(pos);
ListPrint(<);
ListDestory(<);
}
Main.c
#include "List.h"
int main()
{
TestList();
system("pause");
return 0;
}