Doubly linked list
Prior to the discussion of linked storage structure in a node in only a direct successor of the pointer indicates the domain, thus, only the clockwise starting from the back to find a node to other nodes. To find immediate predecessor node, we need to from header starting. in other words, in the single linked list, the execution time NextElem is O (1), and the execution time PriorElem is O (n). to overcome this disadvantage of unidirectional single linked list, it can be used doubly linked list .
node of a doubly linked list has two pointers in fields, one direct successor point, another point immediate predecessor
and similar single list, a doubly linked list table may be circulating, as shown, there are two rings in the list of FIG.
package main.com.cs.test;
public class DoublyLinkedList<T> {
private int size;
private Node<T> head;//链表的投节点
private Node<T> tail;//链表的尾节点
//构建一个null 链表
public DoublyLinkedList() {
this.head =this.tail= new Node<>();
}
private static class Node<T>{
Node<T> Precursor;
T data;
Node<T> next;
public Node(T data){
this(data, null, null);
}
public Node(){
this(null, null, null);
}
public String toString(){
return this.data.toString();
}
Node(T data, Node<T> front, Node<T> next){
this.Precursor = front;
this.data = data;
this.next = next;
}
}
public boolean add(int index, T data) {
if(index<0||data==null)
throw new NullPointerException("index < 0 || data == null");
int j = 0;
Node<T> front = this.head;
//查找要插入结点位置的前一个结点
while (front.next != null && j < index) {
j++;
front = front.next;
}
//创建需要插入的结点,并让其前继指针指向front,后继指针指向front.next
Node<T> q = new Node<T>(data, front, front.next);
//空双链表插入和尾部插入,无需此操作
if(front.next != null) {
//更改front.next的前继指针
front.next.Precursor = q;
}
//更改front的后继指针
front.next = q;
//在尾部插入时需要注意更新tail指向
if(front==this.tail){
this.tail=q;
}
return true;
}
public void printLinkList() { //打印链表
DoublyLinkedList.Node<T> curr = this.head;
if (isEmpty()) {
try {
throw new Exception("linklist is empty");
} catch (Exception e) {
e.printStackTrace();
}
}
while(curr != null){
System.out.print(curr.data+" ");
//判断如果 尾节点的 next 指向 头节点 那么就跳出循环
if (curr.next == head){
return;
}
curr = curr.next;
}
}
public boolean isEmpty(){//判断链表是否为空
return this.head == null;
}
public static void main(String[] args) {
DoublyLinkedList<Integer> mylist = new DoublyLinkedList<Integer>();//构造一个空链表
mylist.add(0,5);
mylist.add(1,3);
mylist.add(2,7);
mylist.add(3,6);
mylist.printLinkList();
}
}