上一篇【数据结构与算法】4.自主实现单链表的增删查改 我们自主实现了单链表的操作,在Java的集合类中LinkedList
底层实现是无头双向循环链表。所以今天我们模拟LinkedList
的实现。
学习双链表之前,做个回顾。
单链表的特点:
双链表的特点:
双链表的定义:
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
指针域(prev):用于指向当前节点的直接前驱节点;
数据域(data):用于存储数据元素;
指针域(next):用于指向当前节点的直接后继节点。
判断链表是否为空,如果为空,将新节点的node
设置为头节点,将新节点的node
设置为尾节点
如果链表不为空,将新节点的node
的next
域设置为头节点,将当前头节点的prev
设置为新节点的node
,更新头节点为新节点的node
动画演示:
代码:
判断链表是否为空,如果为空,将新节点的node
设置为头节点,将新节点的node
设置为尾节点
如果链表不为空,将最后一个节点last
的next
域指向新节点,新节点的prev
域指向最后一个节点,更新尾节点为新节点
动画演示:
代码:
判断索引idnex
是否合法,如果不合法则抛出异常。
判断链表是否为空,如果为空则将新节点设置为头节点和尾节点
如果索引index == 0
,则使用头插法,如果索引index = 链表长度
,则使用尾插法
找到索引节点(当前节点)
将新节点的next
域指向当前节点,新节点的prev
域指向当前节点的前一个节点,当前节点的prev
域指向新节点,更新新节点的上一个节点的next
域指向当前节点。
动画演示:
key
相等,则返回ture
,如果不相等则移动下一个节点继续查找。如果遍历完链表都没有找到key
则返回false
.代码:
prev
域置为空。next
域置为空next
域指向当前节点的下一个节点,更新下一个节点的prev
域指向当前节点的上一个节点代码:
从头节点遍历链表,与删除指定元素的方式一样,删除节点后继续遍历链表,直到遍历完链表,删除所有指定的元素即可。
代码:
代码:
将头节点和尾节点置为空,没有引用指向直接被JVM回收
MyLinkedList
类:
接口:
异常类:
不同点 | ArrayList | LinkedList |
---|---|---|
存储空间上 | 物理上一定连续 | 逻辑上连续,但物理上不一定连续 |
随机访问 | 支持O(1) | 不支持O(n) |
头插 | 需要搬移元素,效率低O(n) | 只需要修改引用的指向,时间复杂度为O(1) |
插入 | 空间不够时需要扩容 | 没有容量的概念 |
应用场景 | 元素高效存储 + 频繁访问 | 任意位置插入和删除频繁 |