双向链表的增删改查
import java.util.NoSuchElementException;
//双向链表
public class MyLinkedList<E> {
public static void main(String[] args) {
MyLinkedList<String> list = new MyLinkedList<>();
list.add("bb");
list.addFirst("aa");
// list.unLinkLast();
list.add("dd");
list.add("ee");
list.add("gg");
list.add(2, "cc");
for (int i = 0; i < list.size; i++) {
String s = list.get(i);
System.out.println(s);
}
}
// 定义节点
private static class Node<E> {
E item;// 节点元素值
Node<E> prev;// 当前节点的上一个节点
Node<E> next;// 当前节点的下一个节点
public Node(Node<E> prev, E item, Node<E> next) {
super();
this.item = item;
this.prev = prev;
this.next = next;
}
}
// 头节点
private Node<E> first;
// 尾结点
private Node<E> last;
// 元素个数
private int size;
// 尾添加元素
private void linkLast(E e) {
// 1.保存尾结点
Node<E> l = last;
// 2.为新元素创建节点,由于是尾节点,所以上一个节点就是原来的last即l,新节点的下一个就是null;
Node<E> newNode = new Node<E>(l, e, null);// 循环链表null改为first
// 3.让last指向新节点
last = newNode;
// 4.将原来的last指向新节点
if (l == null) {
// 说明第一次添加元素,该节点即是首节点,又是尾结点
first = newNode;
} else {
// 说明原来有节点,只要将原来的last的下一个节点指向新节点
l.next = newNode;
}
size++;
}
// 头添加
private void LinkFirst(E e) {
Node<E> f = first;
Node<E> newNode = new Node<E>(null, e, f);// f为原来的first
first = newNode;
if (f == null) {
last = newNode;
} else {
f.prev = newNode;
}
size++;
}
// 向[0 size-1]范围内添加元素
public void linkBefore(E element, Node<E> succ) {
// 找到原来该位置节点的上一个节点
Node<E> pred = succ.prev;
// 创建要添加的节点
Node<E> newNode = new Node<E>(pred, element, succ);
// 将pred的next指向新节点
if (pred == null) {
// 说明添加的位置为零
first = newNode;
} else {
pred.next = newNode;
}
// 将succ的prev指向新节点
succ.prev = newNode;
size++;
}
public void add(int index, E element) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException("下标越界");
}
if (index == size) {
linkLast(element);
} else {
Node<E> succ = node(index);
linkBefore(element, succ);
}
}
public void add(E e) {
linkLast(e);
}
public void addFirst(E e) {
LinkFirst(e);
}
// 判断传进来的下标是否在范围内
private void checkIndex(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("下标越界");
}
}
// 根据下标获取对象
private Node<E> node(int index) {
// 判断index离头近还是尾
if (index < (size >> 1)) {
// 在左边,从头找q
Node<E> n = first;
for (int i = 0; i < index; i++) {
n = n.next;
}
return n;
} else {
// 离尾部近
Node<E> n = last;
for (int i = size - 1; i > index; i--) {
n = n.prev;
}
return n;
}
}
// 根据下标获取元素
public E get(int index) {
checkIndex(index);
return node(index).item;
}
// 删除尾节点
private E unLinkLast() {
// 保存尾结点的元素,作为方法返回值
Node<E> l = last;
// 重新引用一次要被删除的节点
E value = l.item;
// 将倒数第二个节点变为尾结点
last = l.prev;
// 判断删除完毕集合中是否还有元素
if (l.prev == null) {
first = l.prev;
} else {
// 将现在的尾结点的下一个节点置为null
last.next = null;
}
// 优化内存,帮助垃圾回收
l.item = null;
l.prev = null;
size--;
return value;
}
// 删除头节点
private E unlinkFirst() {
Node<E> f = first;
E value = first.item;
first = f.next;
if (first == null) {
last = null;
} else {
first.prev = null;
}
f.item = null;
f.next = null;
size--;
return value;
}
// 删除头节点
public E remove() {
if (first == null) {
throw new NoSuchElementException("集合中没有元素");
}
return unlinkFirst();
}
// 删除尾节点
public E removeLast() {
if (last == null) {
throw new NoSuchElementException("集合中没有元素");
}
return unLinkLast();
}
// 修改元素值
public E set(int index, E newElement) {
checkIndex(index);
Node<E> node = node(index);
E old = node.item;
node.item = newElement;
return old;
}
// 按照下标删除节点
// 按照下标删除元素
private E unlink(Node<E> node) {
E vslue = node.item;
Node<E> prev = node.prev;
Node<E> next = node.next;
if (prev == null) {
// 删除头节点
first = next;
} else {
prev.next = next;
node.prev = null;
}
if (next == null) {
// 删除尾节点
last = prev;
} else {
next.prev = prev;
node.next = null;
}
node.item = null;
size--;
return vslue;
}
public E remove(int index) {
checkIndex(index);
return unlink(node(index));
}
// 获取元素个数
public int size() {
return size;
}
}