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

news2024/12/23 9:50:21

目录

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

一、循环链表

循环链表就是首尾相接的的链表,就是尾节点的指针域指向头节点使整个链表形成一个循环,这就弥补了以前单链表无法在后面某个节点找到前面的节点,可以从任意一个节点找到目标节点,但是现在我们就不能像以前那样停止循环时的判断条件是否为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;
}

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

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

相关文章

Leetcode 540. 有序数组中的单一元素

1.题目基本信息 1.1.题目描述 给你一个仅由整数组成的有序数组&#xff0c;其中每个元素都会出现两次&#xff0c;唯有一个数只会出现一次。 请你找出并返回只出现一次的那个数。 你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复杂度。 1.2.题目地址 https:…

大语言模型入门(二)——提示词

一、什么是提示词 大语言模型&#xff08;LLM&#xff09;的提示词&#xff08;Prompt&#xff09;是与模型交互的关键&#xff0c;它影响着模型的输出结果。提示词&#xff08;Prompt&#xff09;和提示工程&#xff08;Prompt Engineering&#xff09;密切相关。什么又是提示…

详解代理服务器及Squid

一、 代理服务器简介 &#xff08;1&#xff09;什么是代理服务器 代理服务器英文全称为ProxyServer&#xff0c;其主要功能代理网络用户获取网络信息&#xff0c;起到内网和Internet的桥梁作用。 在TCP/IP网络中&#xff0c;传统的通信过程是这样的&#xff1a;客户端向服务…

ROS2 22.04 Carttographer安装

安装环境&#xff1a; Ubuntu22.04 ros2 humble # 下载源文件 git clone https://github.com/ros2/cartographer.git -b ros2 git clone https://github.com/ros2/cartographer_ros.git -b ros2# 使用小鱼一键配置rosdep wget http://fishros.com/install -O fishros &&am…

基于SSM的本科生操行评定管理系统

文未可获取一份本项目的java源码和数据库参考。 1课题名称 基于SSM的本科生操行评定系统 1.2课题来源和选题依据 随着时代的进步和国民生活水平的不断提高&#xff0c;教育也越来越被人们所重视&#xff0c;学校应该培养品学兼优的全方位人才&#xff0c;学生的行为习惯和日…

mac安装redis实践和客户端连接失败问题解决

文章目录 参考文档和网址redis和客户端安装下载Homebrew程序Mac系统设置redis后台运行设置连接密码安装ARDM使用ARDM连接redis错误解决 参考文档和网址 redis官网命令指导文档brew官网地址brew客户端下载地址redis客户端下载地址 redis和客户端安装 下载Homebrew程序 HomeB…

golang grpc进阶

protobuf 官方文档 基本数据类型 .proto TypeNotesGo Typedoublefloat64floatfloat32int32使用变长编码&#xff0c;对于负值的效率很低&#xff0c;如果你的域有可能有负值&#xff0c;请使用sint64替代int32uint32使用变长编码uint32uint64使用变长编码uint64sint32使用变长…

大语言模型入门(一)——大语言模型智能助手

一、大语言模型智能助手 2022年末ChatGPT一经推出&#xff0c;一时间不注册个账号用一下都跟不上潮流了。然而&#xff0c;我们要注册OpenAI的账号使用ChatGPT还是一件比较麻烦的事情&#xff08;懂的都懂&#xff09;。好在&#xff0c;国内各大团队非常给力地及时推出了自研的…

野火STM32F103VET6指南者开发板入门笔记:【1】点亮RGB

硬件介绍 提示&#xff1a;本文是基于野火STM32F103指南者开发板所写例程&#xff0c;其他开发板请自行移植到自己的工程项目当中即可。 RGB-LEDPin引脚&#xff1a;低电平-点亮&#xff0c;高电平-熄灭REDPB5GREENPB0BLUEPB1 文章目录 硬件介绍软件介绍&#xff1a;结构体方式…

三、数据链路层(上)

目录 3.1数据链路层概述 3.1.1术语 3.1.2功能 3.2封装成帧和透明传输 3.2.1封装成帧 ①字符计数法 ②字符&#xff08;节&#xff09;填充法 ③零比特填充法 ④违规编码法 3.2.2透明传输 3.2.3差错控制 差错原因 检错编码 奇偶校验 ☆循环冗余码CRC 例题 纠错…

社区医院疫苗接种预约小程序管理系统SpringBoot+vue

目录 一、项目概述 二、系统架构 1. 技术栈 2. 架构图 三、后端设计 1. 数据模型 2. API 设计 四、前端设计 五、功能实现 1. 用户登录注册 2. 接种建档 3. 疫苗展示 六、总结 一、项目概述 本项目旨在为社区医院提供一个高效便捷的疫苗接种预约管理系统。系统主要…

记一次vue路由跳转登陆之前的页面,参数丢失问题

一、背景 vue3.0&#xff0c;项目登陆之前访问某个可访问的页面&#xff0c;当跳转到需要登陆才能访问的页面时&#xff0c;跳转到登陆页面&#xff0c;登陆后再跳转到登陆之前需要登陆才能访问的页面&#xff0c;跳转时发现参数丢失了。 A页面&#xff08;无需登陆&#xff…

【零基础保姆级教程】MMDetection3安装与训练自己的数据集

最近在跑对比试验&#xff0c;由于MMDetection框架的算法较齐全&#xff0c;遂决定写一篇教程留做参考。若你对流程有问题与疑问欢迎评论区指出 本文运行环境如下供参考&#xff1a; python版本3.9MMDetection版本3.3 一、虚拟环境的搭建 参考该博客搭建基本环境&#xff1…

【开源免费】基于SpringBoot+Vue.JS水果购物网站(JAVA毕业设计)

本文项目编号 T 065 &#xff0c;文末自助获取源码 \color{red}{T065&#xff0c;文末自助获取源码} T065&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

从认识String类,到走进String类的世界

作为一个常用的数据类型&#xff0c;跟随小编一同进入String的学习吧&#xff0c;领略String的一些用法。 1. 认识 String 类 2. 了解 String 类的基本用法 3. 熟练掌握 String 类的常见操作 4. 认识字符串常量池 5. 认识 StringBuffer 和 StringBuilder 一&#xff1a;…

【吊打面试官系列-MySQL面试题】Mysql中的事务回滚机制概述?

大家好&#xff0c;我是锋哥。今天分享关于【Mysql中的事务回滚机制概述&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Mysql中的事务回滚机制概述&#xff1f; 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个…

职称评审一次通过需要注意什么?

谁能想到 被评委会全票通过的职称材料 居然要注意这么多细节 营业执照需要加盖公章 论文需要拆分上传 业绩需要连续提供近几年的 奖项可以加分 一些表格有模板 所以职称评审做材料还是有很多方面需要好好注意一下的&#xff0c;建议还是找机构帮你代理整理&#xff0c;因…

如何使用ssm实现基于web的网站的设计与实现+vue

TOC ssm756基于web的网站的设计与实现vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范…

10. 模块

理想情况下&#xff0c;程序的结构清晰明了。它的运作方式易于解释&#xff0c;每个部分都发挥着明确的作用。 实际上&#xff0c;程序是有机生长的。当程序员发现新的需求时&#xff0c;就会添加新的功能。要使程序保持良好的结构&#xff0c;需要持续的关注和工作。这些工作只…

Linux ssh 免密登录配置

参考资料 ~/.ssh/configについて~/.ssh/configを使ってSSH接続を楽にする.ssh/configファイルでSSH接続を管理する 目录 一. 密钥生成1.1 生成工具1.1.1 OpenSSH1.1.2 Git 1.2 生成命令1.3 注意事项1.4 解决路径中的用户名乱码 二. 将公钥配置到目标服务&#xff0c;免密登录2…