數據結構之雙向鏈表(java版)

記得在一個公司面試上有一道題,寫一個雙向鏈表,包含鏈表的基本操做,插入,刪除,獲取長度等操做,因爲時間匆忙,代碼寫的比較亂,連本身都沒眼看了,後來細想本身歷來都沒有細心的寫過數據結構,總以爲只要原理明白了就萬事大吉了,事實證實,理論和實踐仍是有很大差距的。
水平有限,若是有錯誤,還請不吝賜教java

定義一個內部類Node用於存儲節點元素

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());
    }
}

若是不太瞭解雙向鏈表的結構能夠在紙上畫出每一個Node以及指向關係

相關文章
相關標籤/搜索