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

a3a60f580b674f60bb8cb697e9b13ba6

面试官:你能说说 LinedList 吗?

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

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

Python 小星:双向链表

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

Python 小星:......

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

Python 小星:......

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

Python 小星:最后一个

面试官:回去等消息吧

如果你对链表不是很熟悉,可以先看看

@Python大星

之前的文章

这里用图简单带过:

1、单链表

9707c6266dfd40648eb2e745591d91b9

2、双向链表

9e5368691afc4ad9bc3cbf8ccb94944a

3、循环链表

bd6541271bf84e1a88bc1dbc8403f091

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

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

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

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

LinkedList 源码解析

1、类的属性

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

eb5f8a6ca8ba43ab8ca3b446e4afdfd5

2、 Node 的静态内部类

b649deddeda3498ca81948b818810a82

3、构造函数

19860738bd92469d9bfbce9c111341f3

4、查找 - get

先校验 index 的有效性

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

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

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

5898e2514906406c82dfda7144fc55d3

5、添加 - add

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

754e436ddbb446d8947029848f1df0c5

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

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

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

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

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

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

88c08f502d2d40f3888433bc8b58b869

bc2835be9b444301ac7023c285070ff9

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

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

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

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

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

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

03e5097dd1d74555bc316c3108b1e3c0

63d6146755bb4919888251ed27803da0

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

和 linkFirst 原理一样

ecab716932114c3ead2ce9208b26ad0a

6、修改

先校验 index 的有效性

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

最后给原 node 值赋予新的 element

bd53f8750d234443a69310d39c50adea

7、删除

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

dc4b237f25b046ec9220e3ec82b47f81

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值