数据结构之链表

目录

一:概述

二:链表的种类

1. 单链表

2:单向循环链表

3:双向链表

4:双向循环链表

三:链表与数组

四:扩展


一:概述

 

链表是常见的数据结构,与数组相比,链表稍显复杂。但是链表是非常常用和基本的数据结构。

本篇文章从以下几方面来讲述一下【链表】的知识:

  • 链表的种类

  • 链表的表现形式

  • 链表与数组的比较

二:链表的种类

链表的结构有很多种,我们常用的主要有:单链表,单向循环链表,双向链表,双向循环链表。每种链表都有不同的实现,他们在底层结构中的表现也不相同。

1. 单链表

单链表是链表中最简单的一种。链表在内存中不是一块连续的内存地址,链表通过指针将不连续的内存空间联系在一起,每个独立的内存空间也可以称之为节点。链表的每个节点中不仅仅存储数据,还需要存储下一个节点的地址。链表和数组不一样,数组是一组有序的内存地址,所以,可以按照顺序找到对应的目标数据,链表就只能通过每个节点中存储的下一个节点的地址信息来查找。链表中存储的下一个节点地址叫做后继指针

链表的第一个节点叫做头节点,最后一个节点叫尾节点。头节点记录了一个链表的起始位置,指针指向为null的一个节点就是尾节点。

链表的操作:

链表和数组都可以对数据进行插入删除查找操作。链表在插入删除数据上的性能要比数组要好,在查询上没有数组的性能好。

如下图所示:

链表在插入数据时只需要将插入位置的前驱节点(也就是上一个节点)的后继指针指向插入的节点,然后将插入节点的后继指针指向下一个节点即可。删除节点同样如此。时间复杂度是O(1)

数组是连续的内存地址,插入或删除某个节点元素,意为着有数据需要移动位置,时间复杂度是O(n),这个是比较耗费性能的。

 

 

查询数据时,链表的性能相比较于数组就不够好了。数组由于是连续的内存地址,可以通过下标直接就获取到数据了。时间复杂度是O(1)。单链表只能从头节点开始,一个节点一个节点的遍历。时间复杂度是O(n)。

2:单向循环链表

上图是单向循环链表。单向循环链表和单链表的差异就是尾节点指向的地址,单链表的尾节点指向的是一个为null的地址,单向循环链表的尾节点指向的是头节点的地址,这样,就形成了一个闭环。因此处理的数据序列具有环形结构特点时,适合采用循环单链表。

3:双向链表

双向链表与单向链表相比,就是每个节点中多存储了一个指针,prev(前驱指针),prev指向的就是当前节点的前一个节点。

与单链表相比,双向链表在进行数据存储中会耗费更大的内存空间,但是因为支持双向遍历,所以会带来很大的灵活性。

举个例子:

链表删除一个节点的步骤如下:

(1). 找到要删除的节点

(2). 将目标节点对应的前驱节点的后继指针指向删除节点的下一个节点。

对于第一种情况,查找数据本身就不是链表的强项,时间复杂度是O(n)。对于第二种情况,由于链表是一个一个节点进行遍历的,找到目标要删除的节点后很容易得到后驱节点,但是单链表却无法在一次循环中得到前驱节点,而双向链表的前驱指针可以直接得到。由此,可以看出双向链表的效率要比单链表要高。

java中的LinkedHashMap有类似的实现。

 

4:双向循环链表

 

还有一种常见的就是双向链表和循环链表的结合体,双向循环链表。

三:链表与数组

上述内容中对于链表和数组也进行了一些比较。总结一下:

  1. 数组的查询效率要比链表高。原因是:数组是一块连续的内存地址,可以直接通过下标获取数据。

  2. 链表的删除,插入效率比数组高。原因:数组是一块连续的内存地址,删除其中一个节点数据,会导致后续节点的内存地址发生改变,因为数组的内存地址必须是连续的。插入节点也是一样。

  3. 链表占用的内存空间比数组要大。因为链表在内存中的地址不连续,需要额外存储指针。

四:扩展

数组的访问效率更高,仅仅是因为可以通过下标直接获取指定数据吗?

这是一个原因。还有一个更重要的原因就是数组可以借助CPU的缓存机制,预读数组中的数据。链表在内存中的地址不是连续的,对于CPU缓存支持不友好。原因是因为:CPU在将内存加载到缓存中时,加载的是一个内存块,而不仅仅只加载要操作的数据。对于数组来说,存储空间是连续的,也就是一个内存块,所以CPU在加载到某个下标的时候可以把整个数组都加载到CPU缓存中。而链表是不连续的内存地址,换言之就是很多的内存碎片,垃圾回收器恨不得早点把你回收掉。所以借助CPU缓存的速度,数组查询的性能就比较高

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值