清华大学出版数据结构第五版的链表的使用方法_动画 :相识数组与链表两兄弟...

本文介绍了数组和链表这两种基本数据结构的起源、定义及区别。数组提供高效的随机访问,但插入和删除操作较慢;链表则在内存利用率和插入删除操作上更具优势。数组适合内存连续且需要快速访问的情况,链表则适用于内存不连续且需要频繁插入删除的场景。此外,文章提到了数组和链表在JavaScript中的应用,并列举了一些常见的面试问题,强调了理解数据结构基础的重要性。
摘要由CSDN通过智能技术生成

来自公众号:小鹿动画学编程

写在前边

数组和链表,再陌生不过了。它俩兄弟确是数据结构中最重要的两个部分,小鹿归总了一下所有的数据结构,几乎都是由两者演化而来,所以学好数组和链表变的尤为重要。

对于数据结构无从小手的小伙伴来说,下面小鹿为学习路径准备了脑图,以脑图为主干,向外扩展,加上动画的理解,让你喜欢上数据结构。(脑图网上很多免费的,可以选择喜欢的一款)

111466d7866fe2c5bb251b17cc7ad0df.png

NO.1

由来

在我们刚接触编程语言的时候,我们第一要学习的就是声明一个变量,如果一旦变量多了之后,定义变量的代码就写满屏幕了(一开始刚学习编程的时候就这么干)。

30f6c8caf163a4e95e94023225f3dfd2.gif

声明多个变量过程

那么有人想,为何不把所有相同类型的数据放到一个容器里边,更方便存储和使用。此时,数组就诞生了。

3ce0b2407de63113c7db36772b53e407.gif

声明数组的过程

与其说数组的诞生带来了其他数据的到来,还不如说数组引发了一场“血案”。那么有人看了数组的结构,是在内存中申请的连续内存空间,如果我们想办法把零散的内存像数组一样利用起来不是更加节省内存吗?

聪明啊,那么链表就诞生了,而链表的存储并不是简单的存储同一数据类型的变量的,而是存储一些大型的数据对象,可以说数组和链表的出现,促进了后来更多数据结构的出现。

NO.2

定义

数组:数组是一种线性表的结构,是由一组连续的内存空间组成的。

链表:链表是由零散的内存块串联起来不连续的内存空间组成。

40968200677ed59d62865605d7fc544c.gif

数组和链表的定义

上边说到了线性表结构,那什么是线性表结构呢?以后会遇到很多线性表结构,比如队列、栈等,他们都有一个特点就是:他们存储的数据就像是一条线一样结构,只有前后两个方向。

还有一个需要注意的地方就是有关数组,在 Java 中数组中存储的都是相同的数据类型,而在 JavaScipt 允许存储不相同的数据类型,这一点要区分开,小鹿是以 JS 为主的。

NO.3

数组和链表的区别

1、随机访问

第一个区别就是访问数据的效率。因为数组在内存的内存空间是连续的,对 CPU 的缓存机制非常友好,数组是通过寻址公式就可以快速的将下标对应的元素找到。如下图中所演示:

ca8014880372356fc5f970a319f0ea30.gif

数组寻址过程

为什么说数组连续的内存空间对 CPU 友好,从而加快了访问效率呢?

CPU 读取数据是先在 CPU 缓存中读取的,如果找不到就会去内存查找。为什么会有这种操作呢?就是因为 CPU 的访问数据的速度高,而内存的访问速度很低,所以借助 CPU 缓存。弥补了内存的访问过慢而 CPU 访问过快带来的差异问题。

对于数组来说,存储空间是连续的,所以在加载某个下标的时候顺便可以把几个下标对应的元素也加载到 CPU 缓存中,从而加快了访问数据的效率。

那么链表呢,对 CUP 缓存不是很友好,因为它的存储不是连续的内存,所以访问的时候效率非常低的,与上边的数组寻址形成鲜明的对比。如下图所示:

5435a4b82b76f7b446c05c0bc2a30476.gif

单链表查询数据过程

2、内存消耗

上边我们虽然说到数组访问数组的效率是非常高的,但是数组需要占据连续的内存空间,如果内存空间很多,但是都是不连续的,那么使用链表存储作为首选。

链表中是存在指针的,指针的作用是指向下一个零碎的内存空间地址,所以这个指针的存储也需要开辟一定的空间。如下图所示:

7607026a99ee311e29927b61dc0d0eee.png

链表的存储结构

如果存储的是远远大于指针空间的大对象,几乎可以忽略指针存储内存空间。

4、其他区别

关于数组和链表的区别还有很多,但是它的区别都是根据它自身的特点和结构决定的。

虽然数组内存连续的,随机访问数据特别快,但是插入、删除数据变的非常的低效,因为移动数据需要确保数组的连续性。相反呢,链表访问数据虽然效率低,但是随机插入和删除数据要比数组快很多。我们可以发现还有很多区别就是小鹿上边总结出一句话又比如:数组声明的大小固定的,如果数组一旦元素放不下,需要声明一个大的数组,动态扩容效率非常低(如下图)。但是链表呢,直接在尾部拼接一个内存块就可以了。

76ed04146715956c3284c95a6f84a517.gif

数组的动态扩容

细心的小伙伴可以总结出一个规律就是,空间消耗和时间效率两者是不能同时获得的,而是通常使用空间换时间,或者时间换空间的设计思想,后边的文章会经常的讲到。

NO.4

应用

对于数组和链表的应用其实用途很广的,只不过咱们现阶阶段最先接触到最频繁使用的就是数组了。比如 JS 中的数组的一些方法经常会用到,你能说上几个来呢?

PS:JS 中数组的方法有哪些?这是我第一面试面试官问到我的,想必很多初学者对这种问题模模糊糊,所以题提醒一下基础很重要的哦!

对于链表呢,身边很多小伙伴说项目中很少自己用到,是的,没错,但是在高级架构系统开发中或者一些底层开发中,相比要求很高。比较严格,所以会用到这种像链表这种数据结构,比如:一些缓存的淘汰算法就是使用到了链表(LRU)。

学到现在,是不是发现数据结构并不难,难就难在基础定义、数据结构的一些特点起初没有整明白,导致让你后边学习其他的一些数据结构无从下手了。

NO.5

相关面试题

1、数组和链表的区别什么?

2、手写一个链表,完成增删改查操作。

2、如何判断一个变量是否为数组

3、数组的原生方法有哪些?

4、如何将一个类数组变量转化为数组?

5、说一说ES6中对于数组有哪些扩展

6、数组去重,你能说出多少种方法?

7、如何克隆一个数组?你能说出多少种?

NO.6

小结

我们对上边内容做一个小结,今天主要讲到了数组和链表两种数据结构,而其他的数据结构都是由数组和链表进化而来的,这些会在以后的文章中提到。

然后就是数组和链表各有什么样子的结构和特点,从访问数据效率和内存消耗两个方面进行划分,也从原理上去分析数组之所以高效的原因。对于两者区别是由他们的结构和特点决定的,对于其他的区别,如对数组和链表的其他操作效率等,围绕着这两方向来去区分就可以,后边讲到的其他数据结构也是这样去分析和学习的。

下边是一些数组和链表的应用,现阶段我们接触的数组比较多的,对于链表的学习,会手写链表的基本操作就 OK 了。对于面试相关的也整理了些,面试题的作用是将学到的融会贯通起来,也起到测试成果的作用。


●编号1068,输入编号直达本文

●输入m获取文章目录

程序员求职面试

1055d2ed165540ba982a2baf5565ec67.png

分享程序员找工作经验

程序员笔试、面试题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值