为什么数组查询比链表要快

说什么时间复杂度和空间复杂度太难以理解了,就只通俗而言,说重点。

最常见的说法是因为数组的元素是通过下标来访问的,所以快。但“通过下标来访问”意味着什么?为什么快?

数组是一个最基础的数据结构,其他数据结构底层也有部分会用到数组。

上文(八大基本数据结构)中有提到过数组在物理上是连续存储的,链表是非连续存储的。注意,这是在物理上的区别,在逻辑上他们都是连续存储的(物理上指在你的计算机的硬件上的真实情况,逻辑上指的只是你个人认为的,你不管它怎么来,只管看到的结果,你先看到1,马上看到2,那么你认为1和2是连在一起的)。怎么理解呢?如果了解JVM内存模型,会更好理解,不了解也没关系,以下图为例:

这表示一个堆内存里面放了五个数组,但是这五个数组之间不是连续的,他们位置是随机的,可能连续,也可能不连续,数组创建的过程很死板,就是先想好要多大的空间,比如6个格子,那么好,我就先去占一个大小为6的空间,然后再加进来我的6个元素,这样我的6个元素之间在物理上就是连续的,因为它在硬件上是真实挨在一起的。

同一个数组内的元素是连续的,但是数组与数组之间却不一定是连续的,因此他们之间就有间隙,碎片化空间,那这些空间就不就浪费了吗?显然不是,如链表等其他数据结构的特性刚好可以利用这些琐碎空间,如下图:

但这样,他的元素之间在物理上就不是连续的了。链表的结构呢,分为单向链表和双向链表,还有带头的和不带头的,这里我们只以带头的单向链表为例,其他的先不管。其实链表是一个对象,他的对象里面有一个指针(你可以理解为一个坐标,记录的是你要找的数据的内存地址,为了找到下一个数据),指向第一个元素节点,节点有两个指针,一个指向第一个元素存储的数据,一个指向第一个元素所携带的的指针,指针也是数据,也会占用内存,也有内存地址值;而第一个元素携带的指针指向第二个元素,第二个元素同样有两个指针,一个指向存储的数据,一个指向自身携带的指针,而自身携带的指针指向下一个元素……

这个是逻辑图,而真实过程如下,看不懂的话就不用看,直接看下一个图。

至此,想必能明白物理连续和逻辑连续的区别了。

所以,为什么下标访问会更快,因为下标访问是通过物理上的联系直接过去拿数据,你只要先找到数组的位置,然后直接找第几个就行了,而逻辑上的连续还要先找到第一个,拿到他的指针,再去找第二个节点,再解读他的指针,再找第三个……步骤就繁琐很多。打个比方,你来我图书馆借书,问我《JAVA从入门到放弃》这本书在哪里,我告诉你,你先去第一个书架的第二层找到第一本书《葵花宝典》,里面第一页会告诉你怎么找到这本书,然后你去找到《葵花宝典》第一页,上面写,你再去第二个书架第二层找到《六脉神剑》,里面第一页会告诉你如何找到这本书……然后你被套娃了五次,终于找到了《JAVA从入门到放弃》,这就是非物理连续的恐怖之处,而相比之下,我直接告诉你,第五个书架上第二层的左数第五本就是了,你是不是很快就找到了?

那有人会问了,为什么不在链表头里直接写上所有元素的索引,这样要读第几个元素就直接拿他的指针去找不就可以了吗?没错,但我们链表说的是一对一关系,上述问题属于是一对多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值