双向链表模拟
LinkedList底层结构
- LinkedList底层实现了双向列表和双端队列的特点
- 可以添加任意元素可重复,包括null
- 线程不安全,为实现线程同步
底层操作机制
- LinkedList底层维护了一个双向链表。
- LinkedList中维护了两个属性first和last分别指向首节点和尾节点
- 每个节点对象(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向量表
- 因此LinkedList的元素的添加和删除,不是通过数组来实现的,效率相对较高。
源码操作
/*
public LinkedList() {}
// linkeList: first=null last=null
*/
// 构造一个空链表
LinkedList linkedList = new LinkedList();
// 添加第一个元素
/*
public boolean add(E e) {
linkLast(e);
return true;
}
*/
linkedList.add(1);
/*
//添加
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
*/
// 添加第二个元素
linkedList.add(2);
System.out.println(linkedList);
// 删除节点(默认第一个节点)
/*
//1
public E remove() {
return removeFirst();
}
//2
public E remove() {
return removeFirst();
}
//3
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
*/
linkedList.remove();
简单演示
public class LinkedList_ {
public static void main(String[] args) {
// 模拟双向列表
//创建三个节点
Node rick = new Node("rick");
Node gelnn = new Node("gelnn");
Node lucy = new Node("lucy");
// 连接三个节点形成双向链表
rick.next = gelnn;
gelnn.next = lucy;
lucy.pre = gelnn;
gelnn.pre = rick;
// 创建头节点
Node first = rick;
Node last = lucy;
//遍历
while (true) {
if (first == null) {
break;
}
System.out.println(first);
first = first.next;
}
// 添加节点
Node jack = new Node("jack");
rick.next = jack;
gelnn.pre = jack;
jack.pre = rick;
jack.next = gelnn;
// 重置first指向头结点
first = rick;
System.out.println("添加后");
while (true) {
if (first == null) {
break;
}
System.out.println(first);
first = first.next;
}
}
}
// 表示双向列表的一个节点
class Node {
private Object item; //存放数据的
public Node next; // 指向下一个节点
public Node pre; //指向上一个节点
public Node(Object name) {
this.item = name;
}
@Override
public String toString() {
return "Node name=" + item;
}
}