参考LinkedLits源码
链表中添加节点到B节点之前
如果B节点为头节点,需要将first指针指向B
1.构造节点X
Node<E> X= new Node<>(A, e, B);
2.断开AB之间的链,重新指向X
A.next = X
B.prev = X
private void linkBefore(E e, Node<E> succ) { Node<E> pred = succ.prev; Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) { first = newNode; } else { pred.next = newNode; } size++; }
移除节点B
如果B为尾节点或头节点,直接偏移对应指针
将A.next指向C,将C.prev指向A
A.next = C
C.prev = A
private E unLink(Node<E> node) { E element = node.element; Node<E> prev = node.prev; Node<E> next = node.next; //头节点处理 if (prev == null) { first = next; } else { prev.next = node.next; node.prev = null; } //尾节点处理 if (next == null) { last = prev; } else { next.prev = prev; node.next = null; } node.element = null; size--; return element; }
完整代码
public class MyLinkedList<E> { Node<E> first; Node<E> last; int size = 0; public MyLinkedList() { } /** * 连接到链表首部 * 如果链表为空(头指针为空),则将链表头指针和尾指针指向该节点 * 否则将元素直接连接到链表首部 * * @param e */ private void linkFirst(E e) { Node<E> f = first; Node<E> newNode = new Node<>(null, e, f); first = newNode; if (f == null) { last = newNode; } else { f.prev = newNode; } size++; } /** * 连接到链表尾部 * 如果链表为空(尾指针为空),则将头指针和尾指针指向该节点 * 否则将元素直接连接到尾部 * * @param e */ private void linkLast(E e) { Node<E> l = last; Node<E> newNode = new Node<>(last, e, null); last = newNode; if (l == null) { first = newNode; } else { l.next = newNode; } size++; } /** * 连接到节点的前一个元素 * * @param e * @param succ */ private void linkBefore(E e, Node<E> succ) { Node<E> pred = succ.prev; Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; if (pred == null) { first = newNode; } else { pred.next = newNode; } size++; } /** * 删除节点 * 考虑节点为头指针和尾指针的情况 * * @param node * @return */ private E unLink(Node<E> node) { E element = node.element; Node<E> prev = node.prev; Node<E> next = node.next; //头节点处理 if (prev == null) { first = next; } else { prev.next = node.next; node.prev = null; } //尾节点处理 if (next == null) { last = prev; } else { next.prev = prev; node.next = null; } node.element = null; size--; return element; } /** * 检查元素是否越界 * * @param index * @throws Exception */ private void checkIndex(int index) throws Exception { if (index < 0 || index > size) { throw new Exception("元素越界"); } } /** * 根据位置添加节点 * * @param index * @param e */ public void add(int index, E e) { try { checkIndex(index); if (index == 0) linkFirst(e); else if (index == 1) linkLast(e); else linkBefore(e, searchNode(index)); } catch (Exception e1) { e1.printStackTrace(); } } /** * 将节点直接添加到尾部 * * @param e */ public void add(E e) { linkLast(e); } /** * 直接移除链表尾部元素 * @return */ public E remove(){ return unLink(last); } /** * 移除指定位置的元素 */ public E remove(int index){ E element=null; try { Node<E> node=searchNode(index); element=node.element; unLink(node); } catch (Exception e) { e.printStackTrace(); } return element; } /** * 根据位置查找节点 * 如果位置位于前半部分,从首部开始遍历 * 否则从尾部开始遍历 * * @param index * @return */ private Node<E> searchNode(int index) throws Exception { checkIndex(index); if (index < (size >> 1)) { Node<E> indexNode = first; for (int i = 0; i < index; i++) { indexNode = indexNode.next; } return indexNode; } else { Node<E> indexNode = last; for (int i = size - 1; i > index; i--) { indexNode = indexNode.prev; } return indexNode; } } /** * 遍历元素并输出 * * @return */ public void ergodic() { Node<E> node = first; for (int i = 0; i < size; i++) { System.out.println(node.element); node = node.next; } } class Node<E> { Node<E> prev; Node<E> next; E element; public Node(Node<E> prev, E element, Node<E> next) { this.prev = prev; this.next = next; this.element = element; } } public static void main(String args[]) { MyLinkedList linkedList = new MyLinkedList(); for (int i = 0; i < 10; i++) { linkedList.add("node" + i); } linkedList.ergodic(); System.out.println("------------------------"); for (int i=0;i<5;i++){ linkedList.remove(); } linkedList.remove(3); linkedList.ergodic(); } }