数组实现单链表和双链表

news2024/9/23 3:30:17

全文目录

  • 😀 数组实现的优势
  • 🤔 单链表
    • 😕 初始化
    • 😕 头插
    • 😕 在下标 `k` 后面插入元素
    • 😕 删除下标 `k` 后面的元素
    • 😕 遍历
  • 😵‍💫 双链表
    • 🤨 初始化
    • 🤨 插入
    • 🤨 删除元素
    • 🤨 遍历

😀 数组实现的优势

链表在很多语言的标准库里面都有,基本上是通过 Node 节点来链接下一个节点实现的:

struct Node
{
	int _data;
	Node* _next;
	Node* _prev;    // 双链表
}

这样的链表使用起来虽然方便,但是有两个缺点:

  1. 空间更大,因为有内存对齐的存在
  2. 如果有大量的节点,那么会在耗费大量的时间来开辟节点,效率低

所以一般,如果数据是整数的话可以使用数组来代替链表,可以大幅度地提升效率。

🤔 单链表

通过数组实现,需要用到两个数组,一个用来存放数据 e[],一个用来存放下一个节点的下标 ne[],一个用来标记头结点的位置 head,一个用来标记下一个需要用到的位置 index

实现的样子大概是这样:

在这里插入图片描述

😕 初始化

void init()
{
    head = 0;
    index = 1;
}

同样也可以 head = -1, index = 0 来进行初始化,但是这样的话,后面的操作下标都需要 -1 ,所以个人感觉 上一种方式处理起来更加方便。

😕 头插

void add_head(int x)
{
    e[index] = x;
    ne[index] = head;
    head = index;
    index ++;
}

这里需要清楚的是,如果是没有数据的话,那么节点一定是头插的。这样才能保证 head 的更新和顺利找到尾结点。

😕 在下标 k 后面插入元素

void add(int k, int x)
{
    e[index] = x;
    ne[index] = ne[k];
    ne[k] = index;
    index ++;
}

😕 删除下标 k 后面的元素

void remove(int k)
{
    ne[k] = ne[ne[k]];
}

😕 遍历

for (int i = head; i; i = ne[i])
{
    cout << e[i] << ' ';
}

遍历可能会有一些误导,需要找到初始化的 head 才算是到了尾,

首先这个head指的是链表中头节点的下标,当链表中没有节点时head = 0,但当链表中有值插到头节点的时候,head储存的就是这个值的idx1,通过e[idx1]可以求出这个节点的值。而ne[idx1]就等于head之前的值,即0。如果再在头节点插入一个元素,则head指向这个元素的idx2,而ne[idx2]就等于上一次插入的head值,即idx1。此时,head = idx2,ne[idx2] = idx1,ne[idx1] = 0。若真正理解了这个过程,你的问题就迎刃而解了。拿上述链表举例,在循环链表时,初始的i = head,除非链表为空,否则这个head的值一定不为0,其值应为链表中第一个节点的idx2值,输出e[i]后,有i = ne[i],其含义为i = ne[dix2],由上述论证可知,ne[idx2] = idx1,则i = idx1,满足i != 0,输出e[i]的值。又有i = ne[i],即为i = ne[idx1],可知ne[idx1] = 0,则i = 0,不满足i != 0的循环条件,故循环退出。这个链表的循环依次输出了e[idx2]e[idx1],即链表中的前后两个节点。


😵‍💫 双链表

因为双链表有左右两个指针,所以在实现的时候需要三个数组,一个存储元素 e[],一个存储左节点的下标 l[],一个存储右节点的下标 r[]index 表示用到的下标。

🤨 初始化

初始化数组时,给定左边界和右边界。头结点是从左边界的下一个开始,尾结点就是右边界的前一个。这样可以方便头插和尾插,所以就给定 0为左边界, 1 为右边界, index 从2开始。

因为 index 是从2开始的,所以后面的关于下标的操作都需要加上1

// 初始化
void init()
{
    r[0] = 1;   // 头结点
    l[1] = 0;   // 尾结点
    index = 2;  // 元素的下标从2开始,后面的下标也都需要+1
}

这样初始化可能会觉得很变扭,有点违背我们的思维方式,就会想index能不能从1开始,右边界取2。

答案是不能的,这样会导致index在向后走的时候可能取到右边界,那么对index 进行操作就会导致右边界发生变化。所以要保证 index 不能取到右边界。

🤨 插入

因为是双链表,可以直接找到前一个节点,所以在 k 的左边插入可以表示成在 k 的前一个节点的后面插入,头插就是在左边界的后面插入,尾插就是在右边界的前一个节点后面插入。因此只实现一个插入就好了。

// 在当前节点的后面插入
void insert(int k , int x)
{
    e[index] = x;   
    r[index] = r[k];
    l[index] = k;
    l[r[k]] = index;
    r[k] = index;
    index++;
}

头插:insert(0, x);   // 头插就是在头结点的右边插入

尾插:insert(l[1], x);    // 尾插就是在尾结点的左边插入

在k的左边插入:insert(l[k + 1], x);    // 在左节点的后面插入

在k后插入:insert(k + 1, x);    // 正常插入

🤨 删除元素

// 删除当前节点
void remove(int k)
{
    r[l[k]] = r[k]; 
    l[r[k]] = l[k];
}

🤨 遍历

同样的,双链表的遍历只要找到右边界的位置就好了

for (int i = r[0]; i != 1; i = r[i])
{
    cout << e[i] << ' ';
}

完结散花🌈🌈🌈

在这里插入图片描述

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

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

相关文章

利用Python自制一个批量图片水印添加器

前段时间写了个比较简单的批量水印添加的python实现方式&#xff0c;将某个文件夹下面的图片全部添加上水印。 今天正好有时间就做了一个UI应用的封装&#xff0c;这样不需要知道python直接下载exe的应用程序使用即可。 下面主要来介绍一下实现过程。 首先&#xff0c;还是老…

WebDAV之葫芦儿·派盘 + PDF Expert

PDF Expert 支持WebDAV方式连接葫芦儿派盘。 推荐一款备受称赞的PDF阅读工具PDF Expert,一款超简单的PDF编辑器。 PDF Expert是一款macOS上的办公软件,它具有专业的PDF编辑功能,可以快速从邮件、网页支持PDF打开,支持用户进行阅读、批注等功能,用户可以直接在PDF上进行…

机器学习10线性回归法Linear Regression

文章目录一、线性回归算法简介二、简单线性回归的实现三、向量化运算四、衡量线性回归法的指标&#xff0c;MSE,RMS,MAEMSE均方误差&#xff08;Mean Squared Error&#xff09;RSE均方误差&#xff08;Root Mean Squared Error&#xff09;平均绝对误差MAE&#xff08;Mean Ab…

在职场,如何克服拖延症?

在职场&#xff0c;你遇见过这样的情况吗&#xff1a;领导让你写一份方案&#xff0c;你一拖再拖&#xff0c;直到最后一天才打开电脑。 这就是拖延症的表现。很多人做一件事常常拖到截止时间的临界点&#xff0c;才被压力所迫开始做事。 也有的人是因为觉得自己解决不了事情&…

PXE + Kickstart 服务器批量安装Linux系统

一、无人值守安装服务 使用光盘镜像来安装Linux系统的方法,该方法适用于只安装少量Linux系统的情况。如果生产环境中有数百台服务器都需要安装系统,这种方式就不合时宜了。这时,我们就需要使用PXE + TFTP +HTTP + DHCP + Kickstart服务搭建出一个无人值守安装系统。这种无人…

vue中提示框 this.$confirm如何让提示框换行

let confirmText [案件号为response.businessInformation.claimNo, 点击确认跳转到查勘继续操作该案件,点击取消跳转到新建赔案查询页面] const newDatas [] const h this.$createElement for (const i in confirmText) { newDatas.pu…

「Whale 帷幄」SpaceSight 产品升级 | 打造门店数智化未来

11月&#xff0c;「帷幄数智空间 Whale SpaceSight」迎来新的功能更新&#xff0c;一起来看一看&#xff0c;它将为您的门店数字化带来哪些强大助力。 我们将通过三篇系列文章&#xff0c;为您介绍 SpaceSight 在出入口客流分析、店内客流分析、门店巡检三大场景下&#xff0c;…

[附源码]计算机毕业设计JAVA郑工校园二手交易平台网站

[附源码]计算机毕业设计JAVA郑工校园二手交易平台网站 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM…

HTML学生中秋节日网页设计模板 DIV布局大学生中秋节网页作业制作 八月十五中秋静态网页成品代码下载 中秋节日网页设计作品

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Laravel Valet - macOS 极简主义者的开发环境

1. Lar**el Valet 介绍2. Lar**el Valet 安装3. 测试 Lar**el Valet4. PHP 版本5. 服务站点6. 定制 Valet 驱动7. Valet 常用命令 1. Lar**el Valet 介绍 Lar**el Valet 是 macOS 极简主义者的开发环境。Lar**el Valet 将您的 mac 配置为在您的机器启动时始终在后台运行 Nginx&…

超实用的日志分析工具——Flightplot,你不会还没用过吧

在上一篇文章中已经为大家介绍过Flight Review分析日志工具的具体使用&#xff0c;但是该工具在使用过程中难免存在一些问题&#xff0c;例如&#xff1a;Flight Review工具需要在线浏览&#xff0c;很多时候受制于电脑网络延迟等问题&#xff0c;导致日志信息加载失败&#xf…

win11摄像头黑了用不了的七个解决办法

目录 前言必读 方法一、重置和隐式设置摄像头 方法二、更新windwos驱动 方法三、检查串行总线控制器 方法四、下载驱动精灵来安装驱动 方法五、驱动精灵里面修复 方法六、检查键盘上面有没有物理摄像头按键 方法七、使用万能摄像头 前言必读 读者手册&#xff08;必读&…

职场经验:为什么要学习自动化测试?过来人告诉你答案

学习自动化这个想法&#xff0c;其实自己在心里已经琢磨了很久&#xff0c;就是一直没付诸实践&#xff0c;觉得现在手工测试已经能满足当前的工作需要&#xff0c;不想浪费时间去学习新的东西&#xff0c;有点时间还不如刷刷视频、看看小说等。 为什么要进行自动化测试&#x…

大量节省实施解决方案的时间和成本——AI vision生态系统

AI Vision是一款对用户友好的工具包 基于AI图像处理可以提高各个行业中的竞争力&#xff0c;已经测试并实现应用的用户无不惊讶于这一系统的速度以及出色成效。但不幸的是&#xff0c;AI Vision尚未得到全面评估&#xff0c;可以理解为黑盒&#xff0c;它不像制造商常常声称的…

如何搭建Docker环境

Docker 是一种虚拟化技术&#xff0c;基于 Linux 的容器机制&#xff08;Linux Containers&#xff0c;简称 LXC&#xff09;&#xff0c;可以把它近似地理解成是一个“轻量级的虚拟机”&#xff0c;只消耗较少的资源就能实现对进程的隔离保护 使用 Docker 可以把应用程序和它…

MarchineCubes实现思路总结

MarchineCubes定义 是一种基于体素构建三维模型的方式&#xff0c;有些类似《我的世界》中的堆方块&#xff0c;但实际上&#xff0c;建模是以方块之间的交点为中心点&#xff0c;每个cube表示八个象限的相交模型 实现思路 在三维空间中划分网格&#xff0c;每个网格是一个c…

[附源码]JAVA毕业设计体育竞赛成绩管理系统(系统+LW)

[附源码]JAVA毕业设计体育竞赛成绩管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目…

Java基础之《netty(9)—netty和线程模型概述》

一、netty概述 1、NIO的类库和API繁杂&#xff0c;使用麻烦&#xff1b;需要熟练掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等。 2、需要具备其他的额外技能&#xff0c;要熟悉Java多线程编程&#xff0c;因为NIO编程涉及到Reactor模式&#xff0c;你必须…

Java --- Spring6之Set方法注入

目录 一、注入外部Bean与内部Bean 二、简单类型注入 三、级联属性赋值 四、注入数组 五、List与Set注入 六、Map和Properties注入 一、注入外部Bean与内部Bean public class OrderDao {private static final Logger logger LoggerFactory.getLogger(UserDao.class);public…

led台灯哪个牌子效果最好?2022最新国产led灯品牌排行

目前台灯的发展非常迅速&#xff0c;已经到了全面led灯的时代&#xff0c;传统的卤素灯已经近乎完全淘汰&#xff0c;这不仅仅是跟技术的发展有关&#xff0c;也跟led灯本身的优势有关&#xff0c;各方面很适合做成护眼灯。 护眼灯为什么都是led灯&#xff1f; 护眼台灯使用le…