二重リンクリスト
ポインタの唯一の直接後継ノードにリンクされたストレージ構造の議論の前にのみ後方から出発し、時計回りが他のノードにノードを見つけるために、このように、ドメインを示す。即時先行ノードを見つけるために、我々はからに必要ヘッダ開始。換言すれば、単一のリンクされたリストに、実行時間NextElemはO(1)、及びPriorElemはO(N)であり、実行時間である。一方向単一リンクリストのこの欠点を克服するために、それを使用することができる二重連結リストを。
二重リンクリストのノードはフィールド内の2つのポインタ一個の直接後継ポイント、別の点即時先行有し
と同様の単一のリストに示すように、二重リンクリストテーブルは、循環してもよいし、図のリスト内の2つのリングがあります。
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();
}
}