記得在一個公司面試上有一道題,寫一個雙向鏈表,包含鏈表的基本操做,插入,刪除,獲取長度等操做,因爲時間匆忙,代碼寫的比較亂,連本身都沒眼看了,後來細想本身歷來都沒有細心的寫過數據結構,總以爲只要原理明白了就萬事大吉了,事實證實,理論和實踐仍是有很大差距的。水平有限,若是有錯誤,還請不吝賜教
java
class Node { private Node previous;//前驅節點 private Node next;//後繼節點 private E e;//泛型元素值 public Node(Node previous, Node next, E e) { this.previous = previous; this.next = next; this.e = e; }
下面以removeElement(E value)
爲例簡單介紹node
public void removeElement(E value){ Node index=this.first;//建立index節點指向first節點 while(index!=null){ if(index.e==value)break; index=index.next; }//while循環用於遍歷整個鏈表來獲取指向要刪除的節點指針 index.previous.next=index.next; index.next.previous=index.previous; length--; }
index.previous
表示要刪除節點的前驅節點index.previous.next=index.next;
意思是將前驅節點的後項指針指向要刪除節點的後繼節點面試
同理index.next
表示要刪除節點的後繼節點index.next.previous=index.previous;
意思是將後繼節點的前向指針指向要刪除節點的前驅節點可能有點繞,簡單畫個鏈表結構圖就能夠很明瞭了
數據結構
insertNext(E baseElement,E value)
和insertPrevious(E baseElement,E value)
同理,這裏再也不贅述app
DoubleLinkedList包含兩個節點指針(僞指針,java中沒有指針的概念)first和last,分別指向鏈表的第一個元素和最後一個元素ide
public class DoubleLinkedList<E> { private Node first;//指向第一個元素 private Node last;//指向最後一個元素 private int length=0;//鏈表長度 class Node { private Node previous; private Node next; private E e; public Node(Node previous, Node next, E e) { this.previous = previous; this.next = next; this.e = e; } } /*** * 向頭節點添加元素,節點結構對外應該是不可見的,因此這裏只傳遞一個泛型的值e */ public void addFirst(E e) { if (first == null) {//鏈表爲空判斷 Node node = new Node(null, null, e);//建立一個新的節點,前驅和後繼都爲空 this.first = node; this.last=node;//將first和last指針指向鏈表的第一個元素 length++;//鏈表長度自增一,下同 }else{ Node node=new Node(null,first,e);//鏈表不爲空建立一個前驅爲空,後繼爲當前first節點的節點,值爲傳入的參數e this.first.previous=node;//當前first的前驅設置爲node this.first=node;//將first指針指向新節點 length++; } } /*** *addLast同addFirst */ public void addLast(E e) { if (last == null) { Node node = new Node(null, null, e); this.first = node; this.last=node; length++; }else{ Node node=new Node(last,null,e); this.last.next=node; this.last=node; length++; } } public void insertPrevious(E baseElement,E value){ Node index=this.first; while(index!=null){ if(index.e==baseElement)break; index=index.next; } Node insertValue=new Node(index.previous,index,value); index.previous.next=insertValue; index.previous=insertValue; length++; } public void insertNext(E baseElement,E value){ Node index=this.first; while(index!=null){ if(index.e==baseElement)break; index=index.next; } Node insertValue=new Node(index,index.next,value); index.next.previous=insertValue; index.next=insertValue; length++; } public void removeElement(E value){ Node index=this.first; while(index!=null){ if(index.e==value)break; index=index.next; } index.previous.next=index.next; index.next.previous=index.previous; length--; } public int getLength(){ return length; } @Override public String toString() { StringBuffer sb=new StringBuffer(); Node current=this.first; while(current!=null){ sb.append(current.e+"->"); current=current.next; } return sb.toString(); } public static void main(String[] args) { DoubleLinkedList<String> list=new DoubleLinkedList<>(); list.addLast("value1"); list.addLast("value2"); list.addLast("value3"); list.addLast("value4"); list.addFirst("value0"); list.insertPrevious("value3","insertValue"); list.insertNext("value3","insertValue2"); System.out.println(list.toString()); System.out.println("鏈表的長度是"+list.getLength()); list.removeElement("value3"); System.out.println(list.toString()); System.out.println("鏈表的長度是"+list.getLength()); } }