双向-->带头-->循环链表

目录

一、双向带头循环链表概述

1.什么是双向带头循环链表

2.双向带头循环链表的优势

3.双向带头循环链表简图

二、双向带头循环链表的增删查改图解及代码实现

1.双向带头循环链表的头插

2.双向带头循环链表的尾插

3.双向带头循环链表的头删

4.双向带头循环链表的尾删

5.双向带头循环链表在pos位置前插入节点

6.双向带头循环链表删除pos位置节点


一、双向带头循环链表概述

1.什么是双向带头循环链表

双向:每个节点都带有一个指向下一个节点的指针(next)和一个直向前一个节点的指针(prev);

带头:即链表带有哨兵位头节点,该节点只包含两个指针,不存储有效数据;

循环:哨兵位头节点有一个next指针指向第一个有效数据节点,还有一个prev指针指向哨兵位节点的前一个节点即链表的尾节点,因此实现了链表的循环;

双向带头循环链表的节点类型:

cpp 复制代码
typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

2.双向带头循环链表的优势

双向带头循环链表不需要我们遍历每个节点来找尾节点,对于链表的尾插而言就变得非常简单。由于较单向非循环链表而言,双向带头循环链表多了一个指向前一个节点的指针prev,所以在结构上较为复杂,但实际应用中少了很多的麻烦。

3.双向带头循环链表简图

二、双向带头循环链表的增删查改图解及代码实现

1.双向带头循环链表的头插

示意图:

代码实现:

cpp 复制代码
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* NewNode = Node_New(x);
	ListNode* First = pHead->next;
	NewNode->next = First;
	First->prev = NewNode;
	NewNode->prev = pHead;
	pHead->next = NewNode;
}

2.双向带头循环链表的尾插

示意图:

代码实现:

cpp 复制代码
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* NewNode = Node_New(x);
	ListNode* Tail = pHead->prev;
	NewNode->prev = Tail;
	Tail->next = NewNode;
	NewNode->next = pHead;
	pHead->prev = NewNode;
}

3.双向带头循环链表的头删

示意图:

代码实现:

cpp 复制代码
// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	if (pHead->next == pHead)
	{
		return;
	}
	ListNode* First = pHead->next;
	ListNode* Next = First->next;
	pHead->next = Next;
	Next->prev = pHead;
	free(First);
	First = NULL;
}

4.双向带头循环链表的尾删

示意图:

代码实现:

cpp 复制代码
// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	if (pHead->next == pHead)
	{
		return;
	}
	ListNode* Tail = pHead->prev;
	ListNode* Prev = Tail->prev;
	Prev->next = pHead;
	pHead->prev = Prev;
	free(Tail);
	Tail = NULL;
}

5.双向带头循环链表在pos位置前插入节点

示意图:

代码实现:

cpp 复制代码
// 双向链表在pos位置的前面插入节点
void ListInsert(ListNode* pos, LTDataType x)
{
	ListNode* NewNode = Node_New(x);
	ListNode* Prev = pos->prev;
	Prev->next = NewNode;
	NewNode->prev = Prev;
	NewNode->next = pos;
	pos->prev = NewNode;
}

6.双向带头循环链表删除pos位置节点

示意图:

代码实现:

cpp 复制代码
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	ListNode* Prev = pos->prev;
	ListNode* Hind = pos->next;
	Prev->next = Hind;
	Hind->prev = Prev;
	free(pos);
	pos = NULL;
}
相关推荐
strive-debug41 分钟前
上篇:《排序算法的奇妙世界:如何让数据井然有序?》
数据结构·算法·排序算法
PHASELESS4111 小时前
Java堆结构深度解析:原理、实现与应用全指南
java·开发语言·数据结构
杀神lwz2 小时前
数据结构和算法(六)--栈&队列&堆
数据结构
ん贤2 小时前
图论基础理论
c语言·数据结构·c++·算法·图论
小哲会魔法3 小时前
冒泡排序、插入排序、快速排序、堆排序、希尔排序、归并排序
数据结构·算法·排序算法
Dreams_l4 小时前
顺序表(Arraylist)和链表(Linkedlist)
数据结构·链表
Dominic_Holmes5 小时前
代码随想录算法训练营Day30 | 01背包问题(卡码网46. 携带研究材料)、Leetcode416.分割等和子集
数据结构·python·算法·leetcode
Dovis(誓平步青云)9 小时前
【数据结构】励志大厂版·初阶(复习+刷题):线性表(顺序表)
c语言·数据结构·经验分享·笔记·学习·算法·学习方法
Brookty10 小时前
【算法】归并排序
数据结构·算法·排序算法
星星火柴93612 小时前
数据结构:哈希表 | C++中的set与map
数据结构·c++·笔记·算法·链表·哈希算法·散列表