是单向链表吗_面试官:LinkedList是单向链表还是双向链表?

f3555bb5b21ad64931e5431bf408789c.png

面试官:你能说说 LinedList 吗?

Python 小星:LinedList 数据结构是链表,查询慢,增删快。

面试官:那 LinkedList 是单向链表还是双向链表?

Python 小星:双向链表

面试官:那 LinkedList 是双向循环链表吗?

Python 小星:......

面试官:没事,那我问你 LinkedList 为什么不用单链表,而是用双链表?

Python 小星:......

面试官:那 LinkedList 删除元素,默认是删除最后一个还是第一个元素?

Python 小星:最后一个

面试官:回去等消息吧


如果你对链表不是很熟悉,可以先看看 @Python大星 之前的文章

Python 算法 02--数组和链表(上)

这里用图简单带过:

1、单链表

74ad9eef82c28c03224908d0f284bd58.png

2、双向链表

9a1f27bc9e00eac3cc628b51db9fe9ec.png

3、循环链表

e9e3aaf338b4d779d1ed61743448efa2.png

单链表 和 双向链表的区别???

① 删除单链表中的某个结点时,一定要得到待删除结点的前驱,得到该前驱有两种方法,第一种方法是在定位待删除结点的同时一路保存当前结点的前驱。第二种方法是在定位到待删除结点之后,重新从单链表表头开始来定位前驱。尽管通常会采用方法一。但其实这两种方法的效率是一样的,指针的总的移动操作都会有 2*i 次。而如果用双向链表,则不需要定位前驱结点。因此指针总的移动操作为 i 次。

② 查找时也一样,我们可以借用二分法的思路,从 head(首节点)向后查找操作和 last(尾节点)向前查找操作同步进行,这样双链表的效率可以提高一倍。


相信不少小伙伴在浏览其他博客时,会看到有的地方说 LinkedList 是双向链表,有的地方说是双向循环链表。这个各有其道理,jdk 1.6 ,LinkedList 是双向循环链表,从 jdk 1.7 后,LinkedList 是简单的双向链表。下面我们主要以 jdk 1.8 的 LinkedList 说起。

LinkedList 源码解析

1、类的属性

实际元素个数,首节点,尾节点

eed70906cb7678c7f4d520405cef27e4.png

2、 Node 的静态内部类

74db6ad1b1513de65732489f2d9bf101.png

3、构造函数

b453c39461e1463c986ace4e7b143b6c.png

4、查找 - get

先校验 index 的有效性

在查找时,先比较 index 与 (size >> 1),即 index 与 size 中间值比较。

如果 index 较小,则从 first 开始往 last 方向遍历;

如果 index 较大,则从 last 开始往 first 方向遍历。

054a48c55d70079c2456e2c177cb0d8d.png

5、添加 - add

注意:当从指定位置添加元素,其中可能会使用 node 方法,从查找中我们可以知道,查找当前 index 对应的 node 元素,需要遍历链表,如果增加的元素在中间,在大数据量下,花费时间可能比 ArrayList 要多。

cc4a09a7092aea6d4c5fb82dc5106e96.png

① 插入到第一个元素中 - linkFirst

新添加的元素,前节点 pre 为 null,后节点 next 为原 first 节点。

新的 first 节点为当前添加的 new。

判断 first 是否为空,即添加的 new 是否是第一个元素,

如果为空,则 last 节点 为 当前节点 new;

如果不为空,last 节点不变,原 first 的前节点 pre 变更为 new,后节点 next 不变。

cd8d9555daa33f8bc9d1937361fcf5f8.png
b19b3f6c24f5b50b1dca0b150bdfe00e.png

② 插入到最后一个元素中 - linkLast

新添加的元素后节点 next 为 null,前节点 pre 为原 last 节点。

新的 last 节点为当前添加的 new。

判断 last 是否为空,即添加的 new 是否是第一个元素,

如果为空,则 first 节点为当前节点 new ;

如果不为空,则原 last 节点的后节点 next 为当前节点 new

77f641a21b34902450f47e953c6f9d81.png
9ddca9ce012934a478304d1075d07d84.png

③ 在非空节点前插入元素 - linkBefore

和 linkFirst 原理一样

defc64943e49eff4b104f3a8191eafe8.png

6、修改

先校验 index 的有效性

然后 node 方法返回当前 index 对应的 node 值

最后给原 node 值赋予新的 element

e87e456d654ac8c2146d4b56057fd758.png

7、删除

我们可以看到 LinkedList 默认是从 first 节点开始删除数据的

0a843379411a46aae382e8101f7932cf.png

@Python大星 | 文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值