单链表我们知道了,里面的结构体指针存下一个结构体的地址;而双链表比单链表多出来一个结构体指针存上一个结构体的地址。
// 带头+双向+循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
LTDataType _data;
struct ListNode* _next;
struct ListNode* _prev;
}ListNode;
// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表销毁
void ListDestory(ListNode* pHead);
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);
**
提醒:为什么头删和头插不用二级指针或者返回链表的头地址? 因为我们的哨兵头地址不会变,就是不会改变。
**
.h文件
#pragma once #include#include #include typedef int LTDatatype; typedef struct ListNode { LTDatatype data; struct ListNode* next; struct ListNode* prev; }LTNode; //结点的开辟 LTNode* BuyListNode(LTDatatype x); //初始化 LTNode* ListInit(); //打印 void Listprint(LTNode* phead); //任意在pos前插入数据 void ListInsert(LTNode* pos, LTDatatype x); //任意删除pos位的结点 void ListErase(LTNode* pos); //头插 void ListPushFront(LTNode* phead, LTDatatype x); //尾插 void ListPushBack(LTNode* phead, LTDatatype x); //头删 void ListPopFront(LTNode* phead); //尾删 void ListPopBack(LTNode* phead); //查找 LTNode* listFind(LTNode* phead, LTDatatype x); //销毁 void ListDstory(LTNode* phead);
两个.c文件
#include"list.h"
LTNode* BuyListNode(LTDatatype x)
{
LTNode* node = (LTNode*)malloc(sizeof(LTNode));
if (node == NULL)
{
perror("malloc fail");
exit(-1);
}
node->data = x;
node->next = NULL;
node->prev = NULL;
return node;
}
LTNode* ListInit()
{
LTNode* head = BuyListNode(-1);
head->next = head;
head->prev = head;
return head;
}
void Listprint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("n");
}
void ListInsert(LTNode* pos, LTDatatype x)
{
assert(pos);
LTNode* newnode = BuyListNode(x);
//记住pos前后空间的地址
LTNode* prev = pos->prev;
//插入
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
void ListPushFront(LTNode* phead, LTDatatype x)
{
assert(phead);
ListInsert(phead->next, x);
}
void ListPushBack(LTNode* phead, LTDatatype x)
{
assert(phead);
ListInsert(phead, x);
}
void ListErase(LTNode* pos)
{
assert(pos);
if (pos->next == pos)
return;
LTNode* next = pos->next;
LTNode* prev = pos->prev;
//删除
free(pos);
prev->next = next;
next->prev = prev;
}
void ListPopFront(LTNode* phead)
{
assert(phead);
ListErase(phead->next);
}
void ListPopBack(LTNode* phead)
{
assert(phead);
ListErase(phead->prev);
}
LTNode* listFind(LTNode* phead, LTDatatype x)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void ListDstory(LTNode* phead)
{
assert(phead);
LTNode* cur = phead;
while (cur->next != phead)
{
ListPopFront(cur);
}
}
#include"list.h"
void printfind(LTNode* tail)
{
if (tail)
{
printf("找到%d了n", tail->data);
}
else
{
printf("未找到n");
}
}
void Tect(LTNode* head)
{
ListPushFront(head, 3);
ListPushFront(head, 4);
Listprint(head);
ListPushBack(head, 1);
ListPushBack(head, 2);
Listprint(head);
ListPopFront(head);
Listprint(head);
ListPopBack(head);
Listprint(head);
LTNode* findnode = listFind(head, 3);
printfind(findnode);
LTNode* find = listFind(head, 4);
printfind(find);
ListDstory(head);
if (head->next == head)
{
printf("存储的数据已经删完!n");
Listprint(head);
}
else
{
printf("存储的数据未删完!n");
}
free(head);
}
int main()
{
LTNode* head = ListInit();
Tect(head);
return 0;
}
**
检验结果**



