【数据结构与算法】链表数据结构

什么是链表数据结构?

链表是线性表的一种,但是在存储上和线性表结构的数组有很大的差异,数组的存储在内存上是一块连续的空间,链表却可以理由分散空间进行存储,因此,当内存大小不够,或者内存碎片过多,而此时又需要为一个长度很大数组分配空间,可能就会出现内存不够,触发jvm提起回收内存的情况,甚至抛出OutOfMemoryError异常。但是链表就不用担心这一点,因为无需向数组一样,提前开辟好一块内存连续的空间。链表的长度时增加,占用的内存可以充分利用内存碎片来完成。

链表数据结构的核心就是下面这样的,包含一个保存实际数值的val,还有指向上一个、下一个链表节点的引用或者是指针(java为引用,c为指针),这里描述的是双链表的基础节点数据结构。

 public class ListNode {
     int val;
     ListNode next;
     ListNode pre;
     ListNode(int x) { val = x; }
 }

链表的种类

1.单向链表
对于普通单链表的随机访问时间复杂度为O(n),因为需要从链表头依次顺序查找,但是对于链表结构添加和删除节点的时间复杂度都是O(1)不需要像数组一样进行数据迁移,不过查找插入和删除位置还要单独计算时间复杂度。插入和删除节点其实就是先通过查询找到需要进行操作的位置,然后修改节点的next连接就可以了。被删除的节点如果是C或者是C++需要进行资源回收,如果是java,因为已经没有其他地方引用,GC会自动回收资源。

2.循环链表
循环链表是一种特殊的单链表,实际上循环链表也非常简单,他和单链表的唯一区别就是在尾节点,单链表的尾节点指向null,表示链表结束,循环链表的尾是指向链表头节点。

3.双向链表
我们常见的单向链表因为是一个方向的链接,这就导致无法直接查找前继节点,需要从头节点遍历才行,单向链表查找前继节点的时间复杂度是O(n)。如果我们在一些场景频繁需要查找前继节点那么就可以使用双向链表,双向链表和单向链表的区别就在于在节点结构里多了一个前继节点引用或指针,在维护链表的时候也要多维护一个前继指针的关系。所以同样的数据,双向链表需要的空间要多出O(n),但是双向链表查找前继节点的时间复杂度降到了O(1)。

特点介绍

1.内存中地址非连续,
2.长度可以实时变化
3.不支持随机查找 查找元素时间复杂度O(n)
4.适用于需要进行大量增添/删除元素操作,而对访问元素无要求的程序

Java中的链表数据结构

1.LinkedList
LinkedList是基于双向链表实现的,不论是增删改查方法还是队列和栈的实现,都可通过操作结点实现。
LinkedList根据index查询时采取的是二分法,即index小于总长度一半时从链表头开始往后查找,大于总长度一半时从链表尾往前查找。如果是根据元素查找,则需要从头开始遍历。

2.HashMap,ConcurrentHashMap
采用拉链法解决哈希冲突,拉链法是一种开放散列的解决哈希冲突的形式。所谓 “拉链法” 就是:将链表和数组相结合。也就是说创建一个链表数组,数组中每一格就是一个链表。若遇到哈希冲突,则将冲突的值加到链表中即可。
相比于之前的版本,jdk1.8在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。
tips:封闭散列解决哈希冲突有:开放定址法,再哈希法等。
3.LinkedHashMap
通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。
LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。

总结

对于通过下标随机读取非常多、插入和删除数据是从末尾操作的场景适合用数组,对于随机读较少、插入和删除操作较多的场景适合用链表,对于需要频繁查找前继和后继节点的场景适合用双向链表,对于资源可以循环利用的可以使用循环链表。
通过单向链表和双向链表的介绍,还需要明白可以通过定义数据结构用空间换时间的设计思想。当内存空间充足的时候,如果追求代码执行效率,可以选择空间复杂度更高的数据结构或算法来提高执行效率。

拓展

java中的List集合最常见的有ArrayList,和LinkedList,ArraysList 实现了 RandomAccess 接口, 而 LinkedList 没有实现。为什么呢?

ArraysList 底层是数组,而 LinkedList 底层是链表。数组天然支持随机访问,时间复杂度为 O(1),所以称为快速随机访问。
链表需要遍历到特定位置才能访问特定位置的元素,时间复杂度为 O(n),所以不支持快速随机访问。

ArraysList 实现了 RandomAccess 接口,就表明了他具有快速随机访问功能。 RandomAccess 接口只是标识,并不是说 ArraysList 实现 RandomAccess 接口才具有快速随机访问功能的!

下面再总结一下 list 的遍历方式选择:
实现了RandomAccess接口的ArrayList,优先选择普通for循环 ,其次foreach,
未实现RandomAccess接口的LinkedList, 优先选择iterator遍历(foreach遍历底层也是通过iterator实现的)。
ps:大size的数据,千万不要使用普通for循环

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容

  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 5,737评论 0 13
  • 一.线性表 定义:零个或者多个元素的有限序列。也就是说它得满足以下几个条件:  ①该序列的数据元素是有限的。  ②...
    Geeks_Liu阅读 2,694评论 1 12
  • 链表(上):如何实现LRU缓存淘汰算法? 今天我们来聊聊“链表(Linked list)”这个数据结构。学习链表有...
    GhostintheCode阅读 1,326评论 0 4
  • 20岁到30岁,可能是人生最艰苦的时期。你刚离开学校,摆脱学生气,却发现要面对许多未曾想过的问题。婚姻工作...
    樑生阅读 125评论 0 0
  • 与柔软有关的许多事,比如回忆 仍然停留在潮湿的故乡某个角落 多数时候,酒不能给人温柔,只是酒醉 其实在故乡,还有一...
    林书雁阅读 533评论 2 2