1. 程式人生 > >雙鏈表程式碼實現和講解

雙鏈表程式碼實現和講解

1、什麼是連結串列

  請移步看我前一篇https://www.cnblogs.com/han200113/p/11549338.html

2、雙鏈表和單鏈表有什麼不同?

                                      

  • 雙鏈表相比單鏈表的date域(節點內容)和next(指向下一個節點)多了一個pre(指向前一個節點)
  • 單鏈表只能向後向後查詢,而雙鏈表由於有節點pre,可實現向前和向後查詢
  • 單鏈表的刪除需要藉助前一個節點,雙鏈表可改變自身前後節點的指向實現自我刪除(詳情看程式碼部分)

3、程式碼實現講解

  3.1  新增操作

    迴圈遍歷到連結串列最後和單鏈表一樣,之後的新增操作除了將當前節點新增到最後,還要把當前節點的pre指向前一個節點,這樣才能實現前進後退  

    

 temp.next=personNode;//將當前節點新增到最後一位
 personNode.pre=temp;

 

  //新增操作
    public  void add(PersonNode personNode){
        //head節點不能動,需要一個節點進行輔助遍歷
        PersonNode temp=head;
        while (true){
            if (temp.next==null){ //遍歷連結串列到結尾,跳出迴圈執行新增操作
                break;
            }
            temp=temp.next;  //輔助節點後移
        }
        temp.next=personNode;//將當前節點新增到最後一位
        personNode.pre=temp;
    }

 

  3.2 順序新增

    順序新增我用的單鏈表的順序新增方式也可以,

pnode.pre=temp;

    這句新增與否不影響,希望大神指點

//順序新增
    public  void addBySort(PersonNode pnode){
        //先頂一個指示
        PersonNode temp=head;
        boolean flag=false;
        while (true){
            if (temp.next==null){
                //System.out.println("add遍歷已經結束");
                break;
            }
            if (pnode.no<temp.next.no){

                break;
            }
            else if (pnode.no==temp.next.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            System.out.println("節點已經存在");
        }else {
            pnode.next=temp.next;
            temp.next=pnode;
            pnode.pre=temp;
        }
    }

  3.3 修改操作

  和單鏈表一樣,這裡不再說了,不理解的可以看下我前一篇單鏈表的隨筆

   //修改
    public void UpdateNode(PersonNode personNode){
        if (head.next==null){
            System.out.println("別修改了,這是空連結串列");
            return;
        }
        PersonNode temp=head.next;
        boolean flag=false;
        while (true){
            if (temp==null){
                break;
            }
            if (temp.no==personNode.no){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.no=personNode.no;
            temp.name=personNode.name;
        }else{
            System.out.println("沒找到,不改了");
        }
    }

  3.4 刪除  (重點)

  先看一下單鏈表怎麼刪除的,這裡用前一個節點直接指向下下個節點,孤立它,它就被記憶體回收了

temp.next=temp.next.next;

  我們這裡怎麼實現的自我刪除呢?

        

 

 

temp.pre.next=temp.next;//將要刪除節點的前節點的next指向該節點的下一個節點
temp.next.pre=temp.pre;//將要刪除節點的下一個節點的pre指向該節點的前一個

   還需要注意,如果刪除的是最後一個:

      如果還用上面的會出現空指標異常,為什麼?

      temp已經是最後一個,temp.next不就是空嗎,那temp.next.pre是什麼,空的前一個?

      所以這裡加了個判斷條件if條件

 //刪除
    public void  removeNode(int num){
        PersonNode temp=head.next;//如果不用next,每次temp定位就是前一個節點
        boolean flag=false;
        while (true){
            if (temp==null){//遍歷結束
                break;
            }
            if (temp.no==num){
                flag=true;
                break;
            }
            temp=temp.next;
        }
        if (flag){
            temp.pre.next=temp.next;
            if (temp.next!=null){
                temp.next.pre=temp.pre;
            }
        }else{
            System.out.println("抱歉,沒有找到");
        }
    }

  3.5  列表

    和單鏈表一樣,不在多說

    

    //列表
    public void list(){
        if (head.next==null){
            System.out.println("還找列表?這是個空的");
            return;
        }
        PersonNode temp=head.next;
        while (true){
            if (temp==null){
                System.out.println("好的您已經遍歷完了");
                break;
            }
            System.out.println(temp);
            temp=temp.next;
        }
    }