编程知识:既然已经有数组了,为什么还要链表?

点击蓝字

dfc044bd80673aafc1207b075f82f4db.png

关注我们

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

来源于网络,侵删

对于不少开发者而言,链表(linked list)这种数据结构既熟悉又陌生,熟悉是因为它确实是非常基础的数据结构,陌生的原因是我们在业务开发中用到它的几率的确不大。

在很多情况下,我们用数组就能很好的完成工作,而且不会产生太多的差异,那么链表存在的意义是什么?链表相比于数组有什么优势或者不足吗?

575a04fc6c84715017e6c1b2546d6d23.png

什么是链表

链表是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

从本质上来讲,链表与数组的确有相似之处,他们的相同点是都是线性数据结构,这与树和图不同,而它们的不同之处在于数组是一块连续的内存,而链表可以不是连续内存,链表的节点与节点之间通过指针来联系。

25bb5503d58114be26b9f24ccf08a69e.png

当然,链表也有不同的形态,主要分为三种:单向链表、双向链表、循环链表。

单向链表

单向链表的节点通常由两个部分构成,一个是节点储存的值val,另一个就是节点的指针next。

51252843d59f2dfc71b9fcf951164a52.png

链表与数组类似,也可以进行查找、插入、删除、读取等操作,但是由于链表与数组的特性不同,导致不同操作的复杂度也不同。

查找性能

单向链表的查找操作通常是这样的:

(1)从头节点进入,开始比对节点的值,如果不同则通过指针进入下一个节点

(2)重复上面的动作,直到找到相同的值,或者节点的指针指向null

链表的查找性能与数组一样,都是时间复杂度为O(n)。

插入删除性能

链表与数组最大的不同就在于删除、插入的性能优势,由于链表是非连续的内存,所以不用像数组一样在插入、删除操作的时候需要进行大面积的成员位移,比如在a、b节点之间插入一个新节点c,链表只需要:

a断开指向b的指针,将指针指向c

c节点将指针指向b,完毕

这个插入操作仅仅需要移动一下指针即可,插入、删除的时间复杂度只有O(1).

链表的插入操作如下:

4cd0ba64ca73411a8f57f34fc7166e59.png

链表的删除操作如下:

90c2806296418808f0ccf7a8a223d84a.png

读取性能

链表相比之下也有劣势,那就是读取操作远不如数组,数组的读取操作之所以高效,是因为它是一块连续内存,数组的读取可以通过寻址公式快速定位,而链表由于非连续内存,所以必须通过指针一个一个节点遍历。

比如,对于一个数组,我们要读取第三个成员,我们仅需要arr[2]就能快速获取成员,而链表则需要从头部节点进入,在通过指针进入后续节点才能读取。

应用场景

由于双向链表的存在,单向链表的应用场景比较少,因为很多场景双向链表可以更出色地完成。

但是单向链表并非无用武之地,在以下场景中依然会有单向链表的身影:

(1)撤销功能,这种操作最多见于各种文本、图形编辑器中,撤销重做在编辑器场景下属于家常便饭,单向链表由于良好的删除特性在这个场景很适用。

(2)实现图、hashMap等一些高级数据结构

双向链表

我们上文已经提到,单向链表的应用场景并不多,而真正在生产环境中被广泛运用的正是双向链表。

双向链表与单向链表相比有何特殊之处?

684a1cdd0fee37d454b428780d10cdfe.png

我们看到双向链表多了一个新的指针prev指向节点的前一个节点,当然由于多了一个指针,所以双向链表要更占内存。

别小看双向链表多了一个前置指针,在很多场景里由于多了这个指针,它的效率更高,也更加实用。

比如编辑器的「undo/redo」操作,双向链表就更加适用,由于拥有前后指针,用户可以自由得进行前后操作,如果这个是一个单向链表,那么用户需要遍历链表这时的时间复杂度是O(n)。

真正生产级应用中的编辑器采用的数据结构和设计模式更加复杂,比如Word就是采用Piece Table数据结构加上Command queue模式实现「undo/redo」的,不过这是后话了。

循环链表

循环链表,顾名思义,他就是将单向链表的尾部指针指向了链表头节点:

f8eb68627cfe85c89f01ccd1468f25dd.png

循环链表一个应用场景就是操作系统的分时问题,比如有一台计算机,但是有多个用户使用,CPU要处理多个用户的请求很可能会出现抢占资源的情况,这个时候计算机会采取分时策略来保证每个用户的使用体验。

每个用户都可以看成循环链表上的节点,CPU会给每个节点分配一定的处理时间,在一定的处理时间后进入下一个节点,然后无限循环,这样可以保证每个用户的体验,不会出现一个用户抢占CPU而导致其他用户无法响应的情况。

当然,约瑟夫环的问题是单向循环链表的代表性应用,感兴趣的可以深入了解下。

当然如果是双向链表首尾相接呢?这就是双向循环链表。

在Node中有一类场景,没有查询,但是却有大量的插入和删除,这就是Timer模块。

几乎所有的网络I/O请求,都会提供timeout操作控制socket的超时状况,这里就会大量使用到setTimeout,并且这些timeout定时器,绝大部分都是用不到的(数据按时正常响应),那么又会有响应的大量clearTimeout操作,因此node采用了双向循环链表来提高Timer模块的性能,至于其中的细节就不再赘述了。

插入!
TimersList <-----> timer1 <-----> timer2 <-----> timer4 <-----> timer3 <-----> ......1000ms后执行     1050ms后执行    1100ms后执行    1200ms后执行

小结

至此,我们对链表这个数据结构有了一定的认知,由于其非连续内存的特性导致链表非常适用于频繁插入、删除的场景,而不见长于读取场景,这跟数组的特性恰好形成互补,所以现在也可以回到题目中的问题了,链表的特性与数组互补,各有所长,而且链表由于指针的存在可以形成环形链表,在特定场景也非常有用,因此链表的存在是很有必要的。

73651ba83e7c892a2bc1580b42a1ef1e.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

戳“阅读原文”我们一起进步

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

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

相关文章

jcache_随机JCache内容:多个提供程序和JMX Bean

jcacheJCache&#xff08;JSR 107&#xff09;是用于缓存的Java标准…足够了。 没有更多介绍性的东西。 这是一则速成文章&#xff0c;内容涉及 多个JCache提供程序配置&#xff0c;以及 功能&#xff1a;通过JMX Mbeans的JCache统计信息 管理多个JCache提供程序 如果您只使…

python webbrowser点击_用 Python 实现手机自动答题,这下百万答题游戏谁也玩不过我!...

引言如果谈到这几年手机上各平台最常见的引流福利&#xff0c;必然是答题赢大奖系列小游戏了。像什么头号英雄&#xff0c;百万玩家之类的&#xff0c;充斥在我们生活中&#xff0c;同时也成为了我们生活中常见的娱乐方式。但是有时候就会想&#xff0c;能不能实现手机自动答题…

程序员的年终总结,各种版本各种残

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删朱自清版这几天心里颇不宁静了&#xff0c;眼看上线的日子越来越临近&#xff0c;而项目Bug之多&#xff0c;密密的交叉着&#xff0c;却无从改起…

securecrt哪个版本好用_电脑跑分测试软件哪个好?好用的电脑跑分软件推荐

想要直观的了解自己电脑状况&#xff0c;那么一款好用的电脑跑分软件无疑是必不可少的&#xff0c;毕竟他能够将测试结果用跑分的形式计算出来。那么&#xff0c;电脑跑分软件哪个比较好呢&#xff1f;下面是小编分享的好用的电脑跑分软件推荐&#xff0c;游戏玩家们可不要错过…

C语言,单片机绕不过的坎,你对C语言内存分配了解多少呢

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删一、static在C语言里面可以用来修饰变量&#xff0c;也可以用来修饰函数。1、 先看用来修饰变量的时候。变量在C语言里面可分为存在全局数据区、…

内存 增量数据持久_内存中数据模型和大数据持久性

内存 增量数据持久ORM框架在需要与关系数据库进行交互时可以帮助开发人员。 对于关系数据库&#xff0c;有许多出色的ORM框架&#xff0c;例如Hibernate和Apache OpenJPA&#xff0c;其中一些确实很棒。 如今&#xff0c;大数据正在涌现&#xff0c;越来越多的人开发在大数据上…

自学编程的6个技巧总结

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删有一天&#xff0c;我的一个在学编程的朋友问我&#xff1a;“我想快速学习编程&#xff0c;你有什么好的推荐吗&#xff1f;”我曾在上大学的时…

C语言如何知自身函数的实际地址与大小

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删事情的起因大概是这样……在很久很久以前&#xff0c;我最早用的是MASM&#xff08;Win32ASM&#xff09;写程序&#xff0c;从平台兼容性、开发…

xtext_使用Xtext为Eclipse和IntelliJ开发DSL

xtext在这篇文章中&#xff0c;我们将看到如何开发一种简单的语言。 我们的目标是&#xff1a; 语言的解析器 IntelliJ的编辑器 。 编辑器应具有语法突出显示&#xff0c;验证和自动完成功能 我们还将免费提供Eclipse和Web编辑器的编辑器 &#xff0c;但请包含您的兴奋之处&…

sed 插入多行_Linux三剑客之sed

sed命令用法小记版本&#xff1a;CentOS7▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼好久没更新文章了&#xff0c;项目的事情太多&#xff0c;总得给自己的懒惰找个借口&#xff0c;哈哈~话不多说进入正题创建测试数据[aliscaspark02 a]$ cat data#test the sedThis is the header l…

分享一些超级炫酷的C语言小技巧

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单&#xff0c;并且仍然有一些非常…

C++编程新手容易犯的 10 种编程错误

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删公司每年都会有一定的人员流动&#xff0c;相应地也会招一些应届生补充进来&#xff0c;指导应届生已经成为老员工的必修课了。平日里会我们会经…

Linux上C语言程序编译过程详解

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删本文将介绍如何将高层的C/C语言编写的程序转换成为处理器能够执行的二进制代码的过程&#xff0c;包括四个步骤&#xff1a;预处理&#xff08;P…

C语言,动图展示十大经典排序算法

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删以前也零零碎碎发过一些排序算法&#xff0c;但排版都不太好&#xff0c;又重新整理一次&#xff0c;排序算法是数据结构的重要部分&#xff0c;…

java ee各类组件_在Java EE组件中使用骆驼路线

java ee各类组件从现在开始我一直在与Camel合作&#xff0c;我真的很喜欢它的简单性。 在Java EE之上使用它一直是一个挑战&#xff0c;我最近发表了一篇关于如何做到这一点的演讲&#xff0c;而在Java EE中引导Camel的不同方法实际上建议使用WildFly-Camel Subsystem 。 在正在…

5gnr帧结构特点有哪些_真空离子束刻蚀设备的结构特点有哪些

离子束刻蚀设备有立式、卧式两种结构。通常情况下&#xff0c;该设备以卧式的结构居多&#xff0c;因为采用卧式结构的话&#xff0c;离子源发出的离子束为水平喷射方向&#xff0c;大部分的刻蚀溅射物将落在真空室的底部&#xff0c;可在一定程度上将溅射材料的重新沉积减少。…

老了就不能编程?大龄程序员在线“辟谣”:15 年后,我变得更好了

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删几年前&#xff0c;Quora 上的一个提问在程序员圈内掀起热议&#xff1a;“随着年龄的增长&#xff0c;人们会对编程失去兴趣吗&#xff1f;预计…

wildfly管理控制台_WildFly管理控制台已更新–请求反馈

wildfly管理控制台红帽JBoss企业应用程序平台&#xff08;EAP&#xff09;和WildFly具有共生关系 。 简而言之&#xff0c;红帽JBoss企业应用程序平台&#xff08;JBoss EAP&#xff09;保留了WildFly社区项目&#xff08;以前称为JBoss Application Server&#xff09;的所有创…

性能测试中脚本怎么写_脚本在流程中的性能影响

性能测试中脚本怎么写我们经常看到人们出于各种目的而使用脚本&#xff08;例如&#xff0c;在服务任务&#xff0c;执行侦听器等中&#xff09;。 使用脚本和Java逻辑通常很有意义&#xff1a; 它不需要打包到jar中并放在classpath上 它使流程定义更易于理解&#xff1a;无需…

超炫酷的C语言技巧

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单&#xff0c;并且仍然有一些非常…