当前位置:网站首页>双向循环链表-配有视频讲解
双向循环链表-配有视频讲解
2022-08-10 22:34:00 【_Yi_Xiao】
双向循环链表
1.概念
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
视频讲解:小破站,搜索 Yi_Xiao8 数据结构系列视频
2.数据结构
typedef int ElemType;
//双链表的结点类型
typedef struct DcLinkNode{
ElemType val;
DcLinkNode* prev;
DcLinkNode* next;
}DcLinkNode;
3.生成结点
DcLinkNode* BuyNode(ElemType elem,DcLinkNode* prev,DcLinkNode* next)
{
DcLinkNode* ptr = (DcLinkNode*)calloc(sizeof(DcLinkNode), 1);
assert(ptr != NULL);
ptr->val = elem;
ptr->next = next;
ptr->prev = prev;
return ptr;
}
4.释放结点
void FreeNode(DcLinkNode* p)
{
free(p);
p = NULL;
}
5.初始化双循环链表
//初始化双循环链表
DcLinkNode* InitDcLinkList()
{
DcLinkNode* ptr = BuyNode(-1, NULL, NULL);
ptr->next = ptr;
ptr->prev = ptr;
return ptr;
}
6.插入一个结点
//在pos的前面加入一个新的结点
void Insert(DcLinkNode* pos, ElemType elem)
{
if (pos == NULL) { return; }
DcLinkNode* ptr = BuyNode(elem, pos->prev, pos);
pos->prev->next = ptr;
pos->prev = ptr;
}
//在头部插入一个结点
void PushFront(DcLinkNode* head, ElemType elem)
{
if (head == NULL) { return ; }
Insert(head->next, elem);
}
//在尾部插入一个结点
void PushBack(DcLinkNode* head, ElemType elem)
{
if (head == NULL) { return; }
Insert(head, elem);
}
7.查询一个结点
//查询一个结点
DcLinkNode* FindValue(DcLinkNode* head, ElemType elem)
{
if (head == NULL) { return NULL; }
DcLinkNode* ptr = head->next;
for (; ptr != head && ptr->val != elem; ptr = ptr->next);
return ptr == head ? NULL : ptr;
}
8.删除一个结点
//删除一个结点
void Delete(DcLinkNode* head, DcLinkNode* ptr)
{
if (head == NULL || ptr == NULL || ptr == head) { return; }
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
FreeNode(ptr);
ptr = NULL;
}
//按照值删除
void DeleteValue(DcLinkNode* head, ElemType elem)
{
if (head == NULL) { return ; }
DcLinkNode* ptr = FindValue(head, elem);
Delete(head, ptr);
ptr = NULL;
}
//头部删除
void PopFront(DcLinkNode* head)
{
if (head == NULL || head->next == NULL) { return; }
Delete(head, head->next);
}
//尾部删除
void PopBack(DcLinkNode* head)
{
//错误示范 双循环链表不会出现next 为空
//if (head == NULL || head->next == NULL) { return; }
if (head == NULL || head->next == head) { return; }
Delete(head, head->prev);
}
9.打印双循环链表
//打印双向循环链表
void Print(DcLinkNode* head)
{
if (head == NULL) { return; }
DcLinkNode* ptr = head->next;
//for (; ptr != head ; printf("%d ",ptr->val),ptr = ptr->next);
while (ptr != head)
{
printf("%d ", ptr->val);
ptr = ptr->next;
}
printf("\n");
}
10.判断链表是否为空
//判断链表空不空
bool isEmpty(DcLinkNode* head)
{
return (head != NULL && head->next != head);
}
11.销毁双向循环链表
//销毁双项链表
void Destory(DcLinkNode** head)
{
if (head == NULL) { return; }
while (isEmpty(*head))
{
PopBack(*head);
}
free(*head);
*head = NULL;
}
边栏推荐
猜你喜欢
MySQL: MySQL Cluster - Principle and Configuration of Master-Slave Replication
《DevOps围炉夜话》- Pilot - CNCF开源DevOps项目DevStream简介 - feat. PMC成员胡涛
二叉树 | 递归遍历 | leecode刷题笔记
EL表达式
"DevOps Night Talk" - Pilot - Introduction to CNCF Open Source DevOps Project DevStream - feat. PMC member Hu Tao
OneNote 教程,如何在 OneNote 中整理笔记本?
二叉树 | 迭代遍历 | leecode刷题笔记
自学软件测试不知道该如何学起,【软件测试技能图谱|自学测试路线图】
DC-9靶场下载及渗透实战详细过程(DC靶场系列)
高学历毕业生,该学单片机还是plc?
随机推荐
Distribution Network Expansion Planning: Consider Decisions Using Probabilistic Energy Production and Consumption Profiles (Matlab Code Implementation)
Nodes in the linked list are flipped in groups of k
JS use regular expressions in g model and non g difference
Fatal error: cstring: No such file or directory
BM7 链表中环的入口结点
SDP
实例049:lambda
JS学习 2022080
gcc492 compile `.rodata‘ can not be used when making a PIE object; recompile with -fPIE
How many threads does LabVIEW allocate?
音乐播放器(未完成版本)
Addition of linked lists (2)
JS中使用正则表达式g模式和非g模式的区别
2021 IDEA creates web projects
链表相加(二)
如何成为一名正义黑客?你应该学习什么?
阿里云新增三大高性能计算解决方案,助力生命科学行业快速发展
高学历毕业生,该学单片机还是plc?
DC-7靶场下载及渗透实战详细过程(DC靶场系列)
LeetCode Daily 2 Questions 01: Reverse Strings (both 1200) Method: Double Pointer