1. 程式人生 > 其它 >雙向連結串列原理及應用舉例

雙向連結串列原理及應用舉例

雙向連結串列

雙向連結串列也叫雙鏈表,是連結串列的一種,它的每個資料節點中都有兩個指標,分別指向直接後繼和直接前驅。所以,從雙向連結串列中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向迴圈連結串列。

圖示1:

圖示2:

分析:

1.遍歷與修改實現方式與單鏈表一致

2.新增(預設新增到雙向連結串列最後)

  (1)先找到雙向連結串列的最後一個節點

  (2)temp.next=HeroNode2; //對本例的條件

  (3)HeroNode2.pre=temp;

3.刪除

  (1)因為是雙向連結串列,我們可以實現自我刪除某個節點,直接找到我們要刪除的節點,比如temp

  (2)temp.pre.next=temp.next; //對本例的條件

  (3)temp.next.pre=temp.pre;

應用舉例

使用帶head頭節點的雙向連結串列實現水滸英雄排行榜

程式碼

package com.atxihua;

public class DoubleLinkedListDemo {
    public static void main(String[] args) {
        System.out.println("雙向連結串列測試");
        //建立節點
        HeroNode2 hero4=new HeroNode2(4,"林沖","豹子頭");
        HeroNode2 hero3
=new HeroNode2(3,"吳用","智多星"); HeroNode2 hero2=new HeroNode2(2,"盧俊義","玉麒麟"); HeroNode2 hero1=new HeroNode2(1,"宋江","及時雨"); //建立一個雙向連結串列 DoubleLinkedList doubleLinkedList=new DoubleLinkedList(); doubleLinkedList.add(hero1); doubleLinkedList.add(hero2); doubleLinkedList.add(hero3); doubleLinkedList.add(hero4); doubleLinkedList.list();
//修改 HeroNode2 newHeroNode=new HeroNode2(4,"公孫勝","入雲龍"); doubleLinkedList.update(newHeroNode); System.out.println("修改後的雙向連結串列"); doubleLinkedList.list(); //刪除 doubleLinkedList.del(3); System.out.println("連結串列刪除後的情況"); doubleLinkedList.list(); } } class HeroNode2{ public int no; public String name; public String nickname; public HeroNode2 next;//指向下一個節點,預設為null public HeroNode2 pre;//指向前一個節點,預設為null //構造器 public HeroNode2(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; } //為了顯示方便,重新toString @Override public String toString() { return "HeroNode2{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '\'' + '}'; } } //建立一個雙向連結串列的類 class DoubleLinkedList{ //先初始化一個頭節點,頭節點不要動,不存放具體的資料 private HeroNode2 head=new HeroNode2(0,"",""); //返回頭節點 public HeroNode2 getHead() { return head; } //遍歷雙向連結串列 public void list(){ //判空 if(head.next==null){ System.out.println("連結串列為空"); return; } //因為頭節點不能動,因此我們需要一個輔助變數來遍歷 HeroNode2 temp=head.next; while (true){ //判斷是否到連結串列最後 if(temp==null){ break; } //輸出節點資訊 System.out.println(temp); //將temp後移 temp=temp.next; } } //新增一個節點到雙向連結串列最後 public void add(HeroNode2 HeroNode2){ //因為頭節點不能動,因此我們需要一個輔助變數來遍歷 HeroNode2 temp=head; while (true){ //判斷是否到連結串列最後 if(temp.next==null){ break; } //如果未找到將temp後移 temp=temp.next; } //當退出while迴圈時,temp就指向了連結串列的最後 //形成了一個雙向連結串列 temp.next=HeroNode2; HeroNode2.pre=temp; } //修改一個節點的內容,與單鏈表修改相同 public void update(HeroNode2 newHeroNode2){ //判空 if(head.next==null){ System.out.println("連結串列為空"); return; } //定義一個輔助節點 HeroNode2 temp=head.next; boolean flag=false;//表示是否找到該節點 while (true){ if(temp==null){ break;//已經遍歷完連結串列 } if(temp.no==newHeroNode2.no){ //找到該節點 flag=true; break; } //未找到,後移 temp=temp.next; } if(flag){ temp.name= newHeroNode2.name; temp.nickname= newHeroNode2.nickname; }else{ System.err.println("該英雄不存在!!!請檢查輸入排名是否正確"); } } /* 從雙向連結串列中刪除一個節點 * 說明 * 1.對於雙向連結串列,我們可以直接找到要刪除的這個節點 * 2.找到後,自我刪除即可 * */ public void del(int no){ //判空 if(head.next==null){ System.out.println("連結串列為空,無法刪除"); return; } HeroNode2 temp=head.next;//輔助變數 boolean flag=false;//標誌是否找到刪除的節點 while (true){ if(temp==null){ //已到連結串列的最後 break; } if(temp.no==no){ flag=true; break; } temp=temp.next;//temp後移,遍歷 } if(flag){ temp.pre.next=temp.next; //如果是最後一個節點,就不需要執行下面這句話,否則會出現空指標 if(temp.next!=null){ temp.next.pre=temp.pre; } }else{ System.out.println("要刪除的節點並不存在"); } } }

執行結果:

為了更好的看到雙向連結串列的資料結構,我們直接來看新增之後doubleLinkedList裡的資料

可以看到資料結構與雙向連結串列圖示1完全一致。