定义链表结构
public class DoubleLinkList<T> {
private Node head;
private Node last;
private int size;
}
定义node结构
public class Node<T> {
private T data;
private Node<T> pre;
private Node<T> next;
public Node(T data, Node<T> pre, Node<T> next) {
this.data = data;
this.pre = pre;
this.next = next;
}
}
定义添加node
/**
* 如果便于理解的话 也可以 分三种情况写 插入最后, 插入第一个,插入中间
* @param data
* @param index
*/
public void add(T data, int index) {
if (index == size) { // 插入到最后
addLast(data);
} else {
addFirst(data, index);
}
}
public void add(T data) {
addLast(data);
}
/**
* 从指定位置添加
* (==null)-----newnode----old
* (!=null)pre------newnode------old
*
* @param data
*/
private void addFirst(T data, int index) {
Node<T> oldNode = getNode(index);//获取老的位置节点 新节点插入前面
Node<T> pre = oldNode.pre;
Node<T> newNode = new Node<>(data, pre, oldNode);
oldNode.pre = newNode;
if (pre == null) {//说明至少一个 先走addlast 至少会添加一个
head = newNode;//重新指定head 为新创建的node
} else {
pre.next = newNode;
}
}
/**
* 从最后添加
*
* @param data
*/
private void addLast(T data) {
Node<T> temp = last;// 取出最后一个node
Node<T> newNode = new Node<>(data, temp, null); //新节点前一个节点即是 最后一个last节点 自己为last节点 next 节点为空
last = newNode;// 最后一个节点为当前节点 赋值新的尾部
if (temp == null) {//当前暂无节点 size=0
head = newNode; // 头部和尾部一样 第一个节点
} else {
//添加尾部 头部不用考虑, 尾部已经赋值 然后把它们串起来就ok了
temp.next = newNode;
}
size++;
}
获取node节点
//查询指定索引的结点
Node getNode(int index) {
if (index < (size >> 1)) { //如果索引在前一半。从前往后找
Node x = head;
for (int i = 0; i < index; i++) {
x = x.next;
}
return x;
} else { //索引在后一半,从后往前找
Node x = last;
for (int i = size - 1; i > index; i--) {
x = x.pre;
}
return x;
}
}
删除某个节点数据
/** pre-----deletenode---next
* 删除元素
*/
public void remove(int index) {
if (size == 0 || index < 0 || index > size - 1) {
return;
}
Node<T> node = getNode(index);
Node<T> preNode = node.pre;
Node<T> nextNode = node.next;
if (preNode == null) {//当前为第一个
head = nextNode;
} else if (nextNode == null) {
last = preNode;// 为最后一个
} else {
preNode.next = nextNode;
nextNode.pre = preNode;
}
size--;
}