IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> (数据结构)带头双向循环列表的实现 -> 正文阅读

[数据结构与算法](数据结构)带头双向循环列表的实现

今天船船计划用简单的方式向大家介绍数据结构中重要知识点——带头双向循环列表

目录

1、链表的概念

2、链表的基本分类

2.1分类

2.2 常用链表

2.3常用链表的分析?

3.?带头双向循环链表的实现

3.1头文件包含

3.2用结构体构造单位结点

3.3定义相应函数?

3.4实现相应函数?

3.4.1创建哨兵位+创建链表头节点

3.4.2链表输出函数

3.4.3实现在pos位置之前插入x、删除pos位置函数

3.4.4尾插、头插?

3.4.5?尾删、头删

4.结语


1、链表的概念

我们必须要明确的一件事,要想学习双向带头循环列表我们首先需要了解链表的基本概念和它的几种基本分类

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表
中的指针链接次序实现的 。

下面我将用图象化的形式向您展示链表的概念

?从上图观察我们可以得出一些结论

  1. 链式结构逻辑上连续,但是物理上不一定连续;
  2. 链表中的结点一般都是堆上申请的;
  3. 从堆上申请的空间一般都是按照一定策略分配的,申请的空间可能连续也可能不连续;

2、链表的基本分类

2.1分类

链表的分类有:单向和多向、带头和不带头、循环和不循环,通过排列组合共有8种形式;

1.单向或多向

?2.带头或不带头

3.循环或不循环

2.2 常用链表

实际中我们常用的链表有两种:无头单向非循环列表、带头双向循环链表?

2.3常用链表的分析?

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。


2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是由于其本身的优势,实现的过程会变得十分简单


3.?带头双向循环链表的实现

3.1头文件包含

首先先写出链表实现过程中所需要用的头文件

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

3.2用结构体构造单位结点

typedef int LTDataType;
typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}LTNode;

3.3定义相应函数?

//创建链表的头结点
LTNode* ListInit();
//双向链表打印
void ListPrint(LTNode* phead);
//双向链表尾插
void ListPushBack(LTNode* phead, LTDataType x);
//双向链表头插
void ListPushFront(LTNode* phead, LTDataType x);
//双向链表尾删
void ListPopBack(LTNode* phead);
//双向链表头删
void ListPopFront(LTNode* phead);

// 在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x);
//  删除pos位置的节点
void ListErase(LTNode* pos);

3.4实现相应函数?

3.4.1创建哨兵位+创建链表头节点

//创建哨兵位
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;
}

?prev指向的是结点前一个结点、next指向的是该结点的下一个结点?

//初始化,设置带头一个双向循环列表
LTNode* ListInit()
{
	LTNode* phead = BuyListNode(-1);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

3.4.2链表输出函数

void ListPrint(LTNode* phead)
{
	assert(phead);//检查phead是否为空指针

	LTNode* cur = phead->next;//定义一个指向哨兵位后一位结点的指针,从此处开始遍历
	while (cur != phead)//因为本链表结构循环,因此在指针返回头节点式前需要继续遍历
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

3.4.3实现在pos位置之前插入x、删除pos位置函数

得益于双向带头循环链表的特性,可以通过实现上述两个函数,轻易实现尾插、头插等功能;

?prev指向的是结点前一个结点、next指向的是该结点的下一个结点

// 在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x)
{
	assert(pos);
	LTNode* prev = pos->prev;//先找到结点的前一位
	LTNode* newnode = BuyListNode(x);//申请一个新的结点

	// prve newnode pos
	prev->next = newnode;//将新结点链接到链表上
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}

??

//  删除pos位置的节点
void ListErase(LTNode* pos)
{
	assert(pos);
	LTNode* prev = pos->prev;//找到原结点的前一位
	LTNode* next = pos->next;找到原结点的后一位

	prev->next = next;
	next->prev = prev;
	free(pos);//释放pos位置的空间
}

3.4.4尾插、头插?

//尾插
void ListPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);

	ListInsert(phead, x);
}
//头插
void ListPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);

	ListInsert(phead->next, x);
}

3.4.5?尾删、头删

//尾删
void ListPopBack(LTNode* phead)
{
	assert(phead);

	assert(phead->next != phead);//防止只有单个结点

	ListErase(phead->prev);//函数传入头指针(哨兵位),头指针的prev就是尾结点
}
//头删
void ListPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);//防止只有单个结点

	ListErase(phead->next);//删除头结点的next,也就是链表的第一个结点(头删)
}

4.结语

看到这里,相信老铁们对如何实现带头双向循环列表相应的了解。

我是计算机海洋的新进船长Captain_ldx,如果我的文章能对您有帮助的话,麻烦各位观众姥爷们点赞、收藏、关注,你们的每一次举手之劳都将化为船长的前进动力!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 11:07:37  更:2022-08-06 11:08:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:57:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码