当前位置: 首页 > news >正文

数据结构双向链表和循环链表

目录

  • 一、循环链表
  • 二、双向链表
  • 三、循环双向链表

一、循环链表

循环链表就是首尾相接的的链表,就是尾节点的指针域指向头节点使整个链表形成一个循环,这就弥补了以前单链表无法在后面某个节点找到前面的节点,可以从任意一个节点找到目标节点,但是现在我们就不能像以前那样停止循环时的判断条件是否为NULL了,而是判断是否指向头指针
在这里插入图片描述
在这里插入图片描述
由于我们的操作经常是在链表的首位进行操作,所以我们引进尾指针的概念,这样以后就可以直接找到操作尾节点
在这里插入图片描述
下面是循环单链表的相关代码:

typedef struct
{int data;Lnode* next;
}*CirList,Lnode;//初始化一个循环单链表
bool init_list(CirList& l)
{l = new Lnode;//开辟空间作为头节点if (l == NULL)return false;l->next = l;//头指针的指针域指向自己return true;
}//判断循环单链表是否为空表
bool isEmpty(CirList& l)
{if (l->next == l)return true;return false;
}

二、双向链表

由于单链表无法逆向检索,循环链表逆向寻找元素时间复杂度也是O(n),所以这里提出双向链表的概念,就是给每个元素一个前驱指针,这样我们就可以直接逆向检索上一个元素了,而且时间复杂度为O(1);双向链表的空表里面两个指针装的都是空指针
在这里插入图片描述

#include<iostream>
using namespace std;
typedef struct Lnode
{int data;Lnode* next,*prior;
}*DoubList,Lnode;//初始化一个双向链表
bool init_list(DoubList& l)
{l = new Lnode;if (l == NULL)return false;l->next = NULL;l->prior = NULL;return true;
}//双向链表建立(前插法)
bool insert_list(DoubList& l)
{init_list(l);int x;while (cin >> x && x != 0){Lnode* p = new Lnode{x,l->next,l};if (p == NULL)return false;if (l->next)l->next->prior = p;l->next = p;}return true;
}//双链表建立(后插法)
bool insert_tail_list(DoubList& l)
{init_list(l);int x;Lnode* r =l;while (cin >> x && x != 0){Lnode* p = new Lnode{ x,NULL,r };if (p == NULL)return false;r->next = p;r = p;}return true;
}//按位插入:在i位插入元素e
bool insertElem(DoubList& l, int i, int e)
{if (i < 1)return false;int j=0;Lnode* r = l;while (j < i - 1 && r->next != NULL){r = r->next;j++;}if (j != i - 1)return false;Lnode* p = new Lnode{ e,r->next,r };if (r->next)r->next->prior = p;r->next = p;return true;
}//按值删除元素e
void deleteElem(DoubList&l,int e)
{if (!l->next)cout << "删除失败:链表为空" << endl;Lnode* r = l->next;while (r){if (r->data == e){r->prior->next = r->next;if (r->next)r->next->prior = r->prior;delete r;r = NULL;return;}r = r->next;}
}//打印双链表
void print(DoubList l)
{Lnode* p=l;while (p->next){p = p->next;cout << p->data << "\t";}cout << endl;
}int main()
{DoubList l;insert_list(l);print(l);deleteElem(l, 3);print(l);return 0;
}

三、循环双向链表

即使我们有了双向链表,但是当我们想要在尾节点找到头节点附近某个节点仍然不够快捷,所以就引进了循环双向链表的概念,不过判断条件这些就需要改变:判断结束条件从NULL变为链表名L

#include<iostream>
using namespace std;
typedef struct Lnode
{int data;Lnode* next,*prior;
}*DoubCirList,Lnode;//初始化一个循环双向链表
bool init_list(DoubCirList& l)
{l = new Lnode;if (l == NULL)return false;//指针域都指向自身l->next = l;l->prior = l;return true;
}//双向循环链表建立(前插法)
bool insert_list(DoubCirList& l)
{init_list(l);int x;while (cin >> x && x != 0){Lnode* p = new Lnode{x,l->next,l};if (p == NULL)return false;l->next->prior = p;l->next = p;}return true;
}//双链表建立(后插法)
bool insert_tail_list(DoubCirList& l)
{init_list(l);int x;Lnode* r =l;while (cin >> x && x != 0){Lnode* p = new Lnode{ x,l,r };if (p == NULL)return false;r->next = p;r = p;}return true;
}//按位插入:在i位插入元素e
bool insertElem(DoubCirList& l, int i, int e)
{if (i < 1)return false;int j=0;Lnode* r = l;while (j < i - 1 && r->next != l){r = r->next;j++;}if (j != i - 1)return false;Lnode* p = new Lnode{ e,r->next,r };r->next->prior = p;r->next = p;return true;
}//按值删除元素e
void deleteElem(DoubCirList&l,int e)
{if (l->next==l)cout << "删除失败:链表为空" << endl;Lnode* r = l->next;while (r!=l){if (r->data == e){r->next->prior = r->prior;r->prior->next = r->next;delete r;r = NULL;return;}r = r->next;}
}//打印双链表
void print(DoubCirList l)
{Lnode* p=l;while (p->next!=l){p = p->next;cout << p->data << "\t";}cout << endl;
}int main()
{DoubCirList l;insert_tail_list(l);print(l);return 0;
}

相关文章:

数据结构双向链表和循环链表

目录 一、循环链表二、双向链表三、循环双向链表 一、循环链表 循环链表就是首尾相接的的链表&#xff0c;就是尾节点的指针域指向头节点使整个链表形成一个循环&#xff0c;这就弥补了以前单链表无法在后面某个节点找到前面的节点&#xff0c;可以从任意一个节点找到目标节点…...

go基础面试题汇总第一弹

init函数是什么时候执行的? init的函数的作用是什么&#xff1f; 通常作为程序执行前包的初始化&#xff0c;例如mysql redis 等中间件的初始化 init函数的执行顺序是怎样的&#xff1f; 分不同情况来回答&#xff1a; 在同一个go文件里面如果有多个init方法&#xff0c;它们…...

Redis 实现分布式锁时需要考虑的问题

引言 分布式系统中的多个节点经常需要对共享资源进行并发访问&#xff0c;若没有有效的协调机制&#xff0c;可能会导致数据竞争、资源冲突等问题。分布式锁应运而生&#xff0c;它是一种保证在分布式环境中多个节点可以安全地访问共享资源的机制。而在Redis中&#xff0c;使用…...

百年极限论一直存在百年糊涂话:有正数小于所有正数

百年极限论一直存在百年糊涂话&#xff1a;有正数小于所有&#xff08;任何、任意&#xff09;正数。 “对于每个大于0的ε[ε>0]&#xff0c;都有非0距离数小于ε”显然是病句&#xff1a;有正数小于每个&#xff08;所有&#xff09;正数ε。其中任意&#xff08;任何&am…...

红日靶场1学习笔记

一、准备工作 1、靶场搭建 靶场地址 靶场描述 靶场拓扑图 其他相关靶场搭建详情见靶场地址相关说明 2、靶场相关主机信息 后续打靶场的过程中&#xff0c;如果不是短时间内完成&#xff0c;可能ip会有变化 主机ip密码角色win7192.168.122.131hongrisec2019!边界服务器win…...

【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)

文章目录 从零实现 list 容器&#xff1a;细粒度剖析与代码实现前言1. list 的核心数据结构1.1节点结构分析&#xff1a; 2. 迭代器设计与实现2.1 为什么 list 需要迭代器&#xff1f;2.2 实现一个简单的迭代器2.2.1 迭代器代码实现&#xff1a;2.2.2 解释&#xff1a; 2.3 测试…...

【C#生态园】打造现代化跨平台应用:深度解析.NET桌面应用工具

选择最适合你的.NET UI框架&#xff1a;全面解析六种热门选择 前言 在现代软件开发中&#xff0c;选择合适的桌面应用框架和UI库对于开发人员来说至关重要。本文将介绍几种流行的.NET桌面应用框架和UI库&#xff0c;包括Eto.Forms、Avalonia、ReactiveUI、MahApps.Metro、Mat…...

第二十一章 (动态内存管理)

1. 为什么要有动态内存分配 2. malloc和free 3. calloc和realloc 4. 常⻅的动态内存的错误 5. 动态内存经典笔试题分析 6. 总结C/C中程序内存区域划分 1.为什么要有动态内存管理 我们目前已经掌握的内存开辟方式有 int main() {int num 0; //开辟4个字节int arr[10] …...

机器学习框架总结

机器学习框架是用于构建、训练、评估和部署机器学习模型的工具和库的集合。它们简化了模型开发过程&#xff0c;并提供了预构建的功能、优化的计算性能和对深度学习、监督学习、无监督学习等技术的支持。下面是一些主要的机器学习框架的详细介绍&#xff1a; 1. TensorFlow 1…...

docker pull 超时的问题如何解决

docker不能使用&#xff0c;使用之前的阿里云镜像失败。。。 搜了各种解决方法&#xff0c;感谢B站UP主 <iframe src"//player.bilibili.com/player.html?isOutsidetrue&aid113173361331402&bvidBV1KstBeEEQR&cid25942297878&p1" scrolling"…...

【数学分析笔记】第4章第3节 导数四则运算和反函数求导法则(2)

4. 微分 4.3 导数四则运算与反函数求导法则 双曲正弦函数 sh ⁡ x e x − e − x 2 \sh x\frac{e^x-e^{-x}}{2} shx2ex−e−x​ 双曲余弦函数 ch ⁡ x e x e − x 2 \ch x\frac{e^xe^{-x}}{2} chx2exe−x​ ch ⁡ 2 x − sh ⁡ 2 x 1 \ch^2 x-\sh^2 x1 ch2x−sh2x1 ( e…...

【2024】基于mysqldump的数据备份与恢复

基于mysqldump备份与恢复 mysqldump是一个用于备份 MySQL 数据库的实用工具。 它可以将数据库的结构&#xff08;如数据库、表、视图、存储过程等的定义&#xff09;和数据&#xff08;表中的记录&#xff09;导出为文本文件&#xff0c;这些文本文件可以包含 SQL 语句&#…...

家用无线路由器配置

一.首先进行线路连接。如下图&#xff1a;"光猫LAN口"—网线—"路由器WAN口"。 注意&#xff1a;家用光纤宽带一般选择使用200兆宽带到1000兆&#xff0c;如果网速不达标请查看路由器是否是千兆路由器。千兆路由器通常是双频的&#xff0c;支持两个信号一个…...

模拟算法(4)_外观数列

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 模拟算法(4)_外观数列 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 题目链…...

vsomeip用到的socket

概述&#xff1a; ​ vsomeip用到的socket的代码全部都在implementation\endpoints目录下面&#xff0c;主要分布在下面六个endpoint类中&#xff1a; local_client_endpoint_impl // 本地客户端socket&#xff08;UDS Socket或者127.0.0.1的socket&#xff09;local_server…...

MFC有三个选项:MFC ActiveX控件、MFC应用程序、MFC DLL,如何选择?

深耕AI&#xff1a;互联网行业 算法研发工程师 ​ 目录 MFC ActiveX 控件 控件的类型 标准控件 自定义控件 ActiveX控件 MFC ActiveX控件 标准/自定义控件 MFC ActiveX控件分类 3种MFC如何选择&#xff1f; MFC ActiveX控件 MFC 应用程序 MFC DLL 总结 举例说明…...

边缘概率 | 条件概率

关于什么是边缘概率分布和条件概率分布&#xff0c;在理论上&#xff0c;我自己也还没有理解&#xff0c;那么现在就根据我学习到的理解方式来记录一下&#xff0c;有错误指出&#xff0c;请大家指正&#xff01;&#xff01;&#xff01; 例如&#xff0c;一个箱子里有十个乒乓…...

深入浅出:现代JavaScript开发者必知必会的Web性能优化技巧

亲爱的读者们&#xff0c;欢迎来到本期博客。今天&#xff0c;我们将深入探讨JavaScript开发者在日常工作中如何提升Web性能。在快节奏的Web开发世界中&#xff0c;性能优化至关重要。本文将分享一些实用技巧&#xff0c;帮助你构建快速、高效的Web应用。 1. 使用CDN加速资源加…...

【S32K3 RTD LLD篇5】K344 ADC SW+HW trigger

【S32K3 RTD LLD篇5】K344 ADC SWHW trigger 一&#xff0c;文档简介二&#xff0c;ADC SW HW 触发2.1 软硬件平台2.2 SWADC 软件触发2.3 SWBCTUADC 软件BCTU触发2.4 PITTRIGMUXADC 硬件PIT TRIGUMX触发2.5 EMIOSBCTUHWADC硬件EMIOS BCTU触发2.6 EMIOSBCTUHW LISTADC硬件EMIOS …...

TransFormer 视频笔记

TransFormer BasicsAttention单头注意力 single head attentionQ&#xff1a; query 查寻矩阵 128*12288K key matrix 128*12288SoftMax 归一 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/19e3cf1ea28442eca60d5fc1303921f4.png)Value matrix 12288*12288 MLP Bas…...

Excel也能搞定GRR!不用买昂贵软件,这份保姆级模板和计算指南请收好

Excel也能搞定GRR&#xff01;不用买昂贵软件&#xff0c;这份保姆级模板和计算指南请收好 在制造业质量管理中&#xff0c;测量系统分析&#xff08;MSA&#xff09;是确保数据可靠性的基石。但现实情况是&#xff0c;许多中小企业和初创团队面对动辄上万元的专业统计软件只能…...

药物研发新思路:共价对接工具AutoDock4实战指南(附避坑技巧)

药物研发新思路&#xff1a;共价对接工具AutoDock4实战指南&#xff08;附避坑技巧&#xff09; 在当今药物研发领域&#xff0c;共价抑制剂因其独特的作用机制和显著的治疗优势正受到前所未有的关注。与传统非共价药物相比&#xff0c;这类分子能与靶蛋白形成稳定的共价键&…...

Hunyuan模型如何降本增效?1.8B边缘部署实战案例分享

Hunyuan模型如何降本增效&#xff1f;1.8B边缘部署实战案例分享 1. 模型介绍与核心优势 混元翻译模型1.5版本带来了两个重要更新&#xff1a;18亿参数的HY-MT1.5-1.8B和70亿参数的HY-MT1.5-7B。这两个模型都专注于支持33种语言之间的互译&#xff0c;特别包含了5种民族语言及…...

Flutter状态管理实战:ChangeNotifier与Provider的完美搭配(附完整代码)

Flutter状态管理实战&#xff1a;ChangeNotifier与Provider的完美搭配 在Flutter开发中&#xff0c;状态管理一直是构建复杂应用的核心挑战。当UI需要根据数据变化动态更新时&#xff0c;如何高效、优雅地管理状态流转&#xff0c;直接决定了应用的性能和可维护性。本文将深入…...

动态间隙精准诊断:NHJX-13 型底盘间隙仪机动车底盘安全检测全方案

动态间隙精准诊断&#xff1a;NHJX-13 型底盘间隙仪机动车底盘安全检测全方案在机动车安全环保检测体系中&#xff0c;底盘间隙仪是诊断车辆转向机构、悬挂系统、传动部件间隙状况的核心设备&#xff0c;尤其对大中型客车、重中型货车等营运车辆&#xff0c;其性能直接决定底盘…...

mysql技巧(十六):覆盖索引 vs 回表 —— 让查询效率提升 10 倍的核心技巧

&#x1f4dd; 本章学习目标本章聚焦数据库性能优化&#xff0c;帮助读者彻底掌握覆盖索引与回表的核心原理。通过本章学习&#xff0c;你将全面理解覆盖索引 vs 回表这一核心主题&#xff0c;并能在实际工作中应用这些技巧&#xff0c;让查询效率提升 10 倍以上。 一、引言&am…...

使用AIVideo实现LaTeX学术报告自动转视频教程

使用AIVideo实现LaTeX学术报告自动转视频教程 1. 引言 作为一名科研工作者&#xff0c;你是否曾经为了准备学术会议的视频报告而头疼&#xff1f;传统的视频制作需要录制、剪辑、配音等多个繁琐步骤&#xff0c;耗时耗力。现在&#xff0c;通过AIVideo这个强大的AI视频创作平…...

SoundSwitch音频配置文件深度解析:应用触发和多设备管理的完整指南

SoundSwitch音频配置文件深度解析&#xff1a;应用触发和多设备管理的完整指南 【免费下载链接】SoundSwitch C# application to switch default playing device. Download: https://soundswitch.aaflalo.me/ 项目地址: https://gitcode.com/gh_mirrors/so/SoundSwitch …...

告别重复编码:用快马AI自动生成软件库e7c9的高效调用代码

作为一名经常和第三方库打交道的开发者&#xff0c;我深刻体会到手动编写调用代码的繁琐。尤其是像e7c9这样功能强大的软件库&#xff0c;虽然封装完善&#xff0c;但每次调用都需要反复查阅文档、处理边界情况&#xff0c;效率实在不高。最近尝试用InsCode(快马)平台的AI辅助生…...

AI辅助开发Playwright脚本:处理文件上传与iframe交互难题

AI辅助开发Playwright脚本&#xff1a;处理文件上传与iframe交互难题 最近在做一个Web自动化测试项目时&#xff0c;遇到了两个特别头疼的问题&#xff1a;文件上传和iframe内的富文本编辑器交互。作为一个刚接触Playwright不久的开发者&#xff0c;这些复杂交互让我卡了好几天…...