C++数据结构学习——双向循环链表

双向循环链表特点

**双向链接:**每个节点都包含两个指针,一个指向前一个节点(前驱节点),另一个指向后一个节点(后继节点)。这种双向连接使得在链表中可以轻松地在两个方向上遍历节点。

**循环性质:**最后一个节点的后继节点指向第一个节点,形成一个环状结构。这意味着可以无限循环遍历链表,因为没有真正的末尾。

**灵活性:**由于双向链接,可以方便地在链表中插入、删除和移动节点,而不需要像单链表那样需要迭代查找前一个节点。

**前向和后向遍历:**可以从任何节点开始,向前或向后遍历整个链表。这对于需要双向遍历的情况非常有用,例如在双向队列(deque)或编辑器中。

**常见应用:**双向循环链表常用于实现循环队列、双向队列、LRU(最近最少使用)缓存算法、文本编辑器的撤销和重做功能等。

哨兵位

数据结构中的"哨兵位"通常指的是一种特殊的元素或节点,它在数据结构中扮演了特殊的角色,通常用于简化算法的实现、边界情况的处理或者提高性能。哨兵位并不包含实际的数据,其主要作用是占据一个特定的位置,以便更容易处理数据结构的边界情况。

C语言代码实现

声明文件

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;}LTNode;LTNode* BuyListNode(LTDataType x);
LTNode* ListInit(); //双向链表初始化
void LTPrint(LTNode* phead); //Print void ListPushBack(LTNode* phead, LTDataType x); //尾插
void ListPopBack(LTNode* phead); //尾删void ListPushFront(LTNode* phead, LTDataType x); //头插
void ListPopFront(LTNode* phead); //头删LTNode* LTFind(LTNode* phead, LTDataType x); //查找void LTInsert(LTNode* pos, LTDataType x); //在pos之前插入x
void LTErase(LTNode* pos); //删除pos位置的数据bool LTEmpty(LTNode* phead); //判断双向链表是否为空
size_t LTSize(LTNode* phead); //长度
void LTDestroy(LTNode* phead); //销毁链表

实现文件

#include "List.h"LTNode* BuyListNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode)); if (node == NULL) {perror("malloc fail...");return -1;}node->data = x;node->next = NULL;node->prev = NULL;return node;
}LTNode* ListInit() 
{LTNode* phead = BuyListNode(-1);phead->next = phead; phead->prev = phead;return phead;
}void LTPrint(LTNode* phead) // Print double-link list
{assert(phead); // ensure phead is not empty LTNode* cur = phead->next;while (cur != phead){printf("%d <->", cur->data);cur = cur->next;}printf("\n");}void ListPushBack(LTNode* phead, LTDataType x) 
{assert(phead); LTNode* newnode = BuyListNode(x);LTNode* tail = phead->prev; newnode->next = phead; newnode->prev = tail;tail->next = newnode; phead->prev = newnode; }void ListPopBack(LTNode* phead)
{assert(phead);assert(phead->next != phead); LTNode* tail = phead->prev;LTNode* tailPrev = tail->prev;tailPrev->next = phead;phead->prev = tailPrev;free(tail); 
}void ListPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyListNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode; newnode->prev = phead;
}void ListPopFront(LTNode* phead) // head deletion
{assert(phead);assert(phead->next != phead);LTNode* cur = phead->next; LTNode* cur_next = cur->next;phead->next = cur_next;cur_next->prev = phead;free(cur); //freeing this node
}LTNode* LTFind(LTNode* phead, LTDataType x) //Find the position of data x
{assert(phead);LTNode* cur = phead->next;while (cur->next != phead){if (cur->data == x) //find{return cur; //return the data's node}cur = cur->next; //if not find, pointer pointing to the next node}return; //not find
}void LTInsert(LTNode* pos, LTDataType x) //在pos之前插入x
{assert(pos);LTNode* newnode = BuyListNode(x); //new node that data is xLTNode* prev = pos->prev;newnode->prev = prev;newnode->next = pos;prev->next = newnode;pos->prev = newnode;
}void LTErase(LTNode* pos) //删除pos位置的数据
{assert(pos);LTNode* prev = pos->prev;LTNode* next = pos->next;free(pos);prev->next = next;next->prev = prev;
}bool LTEmpty(LTNode* phead) //判断双向链表是否为空
{//assert(phead);//if (phead->next == phead)//{//	return true;//}//else//{//	return false;//}return phead->next == phead;
}size_t LTSize(LTNode* phead) //长度
{assert(phead);size_t counter = 0;LTNode* cur = phead;while (cur != phead){counter++;cur = cur->next;}return counter;
}void LTDestroy(LTNode* phead) //销毁链表
{assert(phead);LTNode* cur = phead;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL; //这里置空不起作用}

测试代码

#include "List.h"void ListTest_1()
{LTNode* phead = ListInit();ListPushBack(phead, 10);ListPushBack(phead, 20);ListPushBack(phead, 30);ListPushBack(phead, 40);LTPrint(phead); //Print double-link listLTNode* pos = LTFind(phead,30); //Find the position of data if (pos->data == 30){printf("找到了!!");}else{printf("没找到!!");}LTInsert(pos, 100);//ListPopBack(phead);//ListPopBack(phead);//ListPopBack(phead);//ListPopFront(phead); //ListPopFront(phead);//ListPopFront(phead);//ListPopFront(phead);LTErase(pos);LTPrint(phead);
}int main()
{ListTest_1();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/56393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp scrollview 滚动最新位置

uniapp 效果是模拟发送聊天信息&#xff0c;需要scrollview在收到新消息时滚动到底部最新的位置 项目是vue2的&#xff0c;代码如下 // 第一种 高度固定值 scrollToBottom(selector) {this.$nextTick(() > {const dom uni.createSelectorQuery().in(this).select(selecto…

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…

【Golang】什么是内存逃逸?

文章目录 要从C/C谈起Golang的内存逃逸 要从C/C谈起 在C/C中&#xff0c;局部变量被分配到栈区&#xff0c;一旦当前函数执行完毕&#xff0c;局部变量占用的内存也将被释放&#xff0c;因此以下代码无法将数组的内容传递出去。 int *getArray() {int array[7] {1, 2, 3, 4,…

什么是数据中心IP,优缺点是什么?

如果根据拥有者或者说发送地址来分类的话&#xff0c;可以将代理分为三类&#xff1a;数据中心ip,住宅ip,移动ip 本文我们来了解数据中心ip的原理以及他们的优势劣势&#xff0c;才能选择适合自己的代理。 一、什么是数据中心ip代理&#xff1f; 数据中心ip是由数据中心拥有…

victoriametrics获取指标情况脚本

get_job.sh脚本 #!/bin/bash #获取所有的job list&#xff0c;循环获取vm的job指标推送量&#xff0c;累加整个x月份的指标推送量#线下 #ip_port"x.x.x.x:80" #线上 ip_port"x.x.x.x:80"get_jobcurl -sG "http://$ip_port/select/0/prometheus/api/v…

浏览器输入一个URL之后发生了什么?

URL解析DNS解析TCP连接TSL连接HTTP请求TCP挥手接收并解析响应 URL 解析 主要分为&#xff1a; 协议&#xff0c;eg http,https域名或者ip地址&#xff0c;eg www.baidu.com 域名相对于ip地址来说&#xff0c;更方便人们记忆&#xff0c;但是实际的网络传输中使用的是ip地址 端…

一、使用maven新建springboot

1. 新建maven项目 2. 修改pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:…

SSM框架和Spring Boot+Mybatis框架的性能比较?

SSM框架和Spring BootMybatis框架的性能比较&#xff0c;没有一个绝对的答案&#xff0c;因为它们的性能受到很多因素的影响&#xff0c;例如项目的规模、复杂度、需求、技术栈、团队水平、测试环境、测试方法等。因此&#xff0c;我们不能简单地说哪个框架的性能更好&#xff…

widnows 制作winpe启动盘

下载 官网 大白菜官网,大白菜winpe,大白菜U盘装系统, u盘启动盘制作工具 点击装机版&#xff0c;进行下载&#xff0c;等待下载完成 安装 解压 双击exe运行 插入u盘 识别到的u盘 点击【一键制作成usb启动盘】 点击确定&#xff0c;等待制作完成 重启电脑&#xff0c;选择从…

机器学习深度学习——NLP实战(自然语言推断——微调BERT实现)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——针对序列级和词元级应用微调BERT &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文…

LeetCode5:最长回文子串、LeetCode647:回文子串

文章目录 LeetCode647&#xff1a;回文子串题目示例提示解题思路解题代码复杂度 LeetCode5:最长回文子串题目示例提示解题思路解题代码复杂度 总结 LeetCode647&#xff1a;回文子串 题目 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字…

Module not found: Error: Can‘t resolve ‘vue-pdf‘ in ‘xxx‘

使用命令npm run serve时vue项目报错&#xff1a; Module not found: Error: Cant resolve vue-pdf in xxx 解决方案&#xff1a; 运行命令&#xff1a; npm install vue-pdf --save --legacy-peer-deps 即可解决。 再次顺利执行npm run serve

webrtc在js里的实现

WebRTC&#xff08;Web Real-Time Communication&#xff09;是一项开放的浏览器技术&#xff0c;它允许浏览器之间建立点对点&#xff08;peer-to-peer&#xff09;连接&#xff0c;实现音频、视频、文件的传输和通信。它的实现一般需要使用JavaScript语言。 在JavaScript中&…

Linux系统USB摄像头测试程序(四)_视频旋转及缩放

下面的程序实现了视频的旋转及缩放&#xff0c;窗口中点击鼠标左键视频向左旋转&#xff0c;点击鼠标右键视频向右旋转并且视频缩小了二分之一。程序中首先把yvyv422转换成了RGB24&#xff0c;然后利用opencv进行了旋转和缩放&#xff0c;其后用sdl2进行了渲染。使用了ffmpeg、…

问道管理:市盈率市净率两个指标含义怎么算?

市盈率和市净率是出资领域常用的两个目标&#xff0c;用于评价公司的估值和出资的报答状况。本文将从多个视点剖析这两个目标的含义和计算方法&#xff0c;帮助读者更好地了解和运用它们。首先&#xff0c;市盈率&#xff08;P/E ratio&#xff09;是用来衡量公司股票价格与每股…

程序运行的马甲:进程(1/7)

一个可执行文件被加载到内存中运行时&#xff0c;它在内存空间的分布如图所示&#xff1a; 在内存中有专门的堆栈空间&#xff0c;函数的局部变量是保存在栈中的&#xff0c;使用 malloc 申请的动态内存是在堆空间中分配的&#xff0c;它们是程序运行时比较特殊的两块内存区域&…

从上帝视角俯瞰vue2路由(简单易懂)

文章目录 路由原理&#xff08;hash&#xff09;路由安装和使用&#xff08;vue2&#xff09;路由跳转路由的传参和取值嵌套路由路由守卫完整代码 路由原理&#xff08;hash&#xff09; 单页应用的路由模式有两种 哈希模式&#xff08;利用hashchange 事件监听 url的hash 的…

php图片批量压缩并同时保持清晰度

php图片压缩可以通过GD库来实现。以下是一个使用GD库进行图片压缩的示例代码&#xff1a; // 原始图片路径 $sourceImage path/to/source/image.jpg; // 压缩后保存的路径及文件名 $compressedImage path/to/compressed/image.jpg; // 压缩后的图片质量&#xff08;1-100&…

2.Vue报错Cannot read properties of undefined (reading ‘then‘)

1.出现报错 Cannot read properties of undefined (reading ‘then’)&#xff0c; 代码为 uploadFile(e.target.files[0]).then((res) > {alert(JSON.stringify(res));});2.原因 是因为uploadFile方法没有返回值&#xff0c;于是我又检查了一遍代码&#xff0c;发现我的r…

数据挖掘-关联规则学习-Apriori算法原理

数据挖掘-关联规则学习-Apriori算法原理 引言&#xff1a;一、关联分析是什么&#xff1f;二、基本概念1. 项2. 项集3. 支持度4. 置信度5. 提升度6. 频繁项集 三、关联分析过程四、Apriori算法原理五、程序实现 引言&#xff1a; 比如你女朋友&#xff0c;低头玩手指沉默&…