雙向鏈表的應用實例


管理單向鏈表的缺點分析:

  1. 單向鏈表,查找的方向只能是一個方向,而雙向鏈表可以向前或者向后查找。
  2. 單向鏈表不能自我刪除,需要靠輔助節點 ,而雙向鏈表,則可以自我刪除,所以前面我們單鏈表刪除節點時,總是找到 temp,temp 是待刪除節點的前一個節點。

雙向鏈表如何完成遍歷,添加,修改和刪除的思路

 

 

  1) 遍歷 :和單鏈表一樣,只是可以向前,也可以向后查找
  2) 添加 (默認添加到雙向鏈表的最后)
    (1)先找到雙向鏈表的最后這個節點
    (2) temp.next = newNode; 
    (3) newNode.pre = temp; 
  3) 修改 思路和原來的單向鏈表一樣
  4) 刪除
    (1) 因為是雙向鏈表,因此,我們可以實現自我刪除某個節點
    (2) 直接找到要刪除的這個節點,比如 temp
       temp.pre.next = temp.next; 
       temp.next.pre = temp.pre;//若刪除的是最后一個節點,會有空指針異常 

 

代碼實現

1. class doublelinkedlist {  
2.     //先初始化一個頭節點,頭節點不能動,不存放具體數據  
3.     private hero head = new hero(-1, "", "");  
4.   
5.     //添加節點  
6.     public void add(hero h) {  
7.         //因為head節點不能動,因此我們需要一個輔助變量temp  
8.         hero temp = head;  
9.         //遍歷鏈表,找到最后一個節點  
10.         while (true) {  
11.             if (temp.getNext() == null) {  
12.                 break;  
13.             }  
14.             //如果沒有到最后,將temp后移  
15.             temp = temp.getNext();  
16.         }  
17.         //當退出while循環時,temp就指向了鏈表的最后  
18.         //將鏈表的最后一個節點的next指向要添加的這個節點  
19.         //將要添加的這個節點的pre指向鏈表的最后一個節點  
20.         temp.setNext(h);  
21.         h.setPre(temp);  
22.     }  
23.   
24.     //第二種方式在添加英雄時,根據排名將英雄插入到指定位置  
25.     //(如果有這個排名,則添加失敗,並給出提示)  
26.     public void addByOrder(hero h) {  
27.         //因為頭節點不能動,因此我們仍然通過一個輔助指針(變量)來幫助找到添加的位置  
28.         hero temp = head;  
29.         boolean flag = false;// flag 標志添加的編號是否存在,默認為 false  
30.         while (true) {  
31.             if (temp.getNext() == null) {//說明 temp 已經在鏈表的最后  
32.                 break;  
33.             } else if (temp.getNext().getNum() > h.getNum()) {//位置找到,就在 temp 的后面插入  
34.                 break;  
35.             } else if (temp.getNext().getNum() == h.getNum()) {//說明希望添加的 heroNode 的編號已然存在  
36.                 flag = true;  
37.                 break;  
38.             }  
39.             temp = temp.getNext();//后移,遍歷當前鏈表  
40.         }  
41.         if (flag) { //不能添加,說明編號存在  
42.             System.out.println("添加的序號為" + h.getNum() + "的英雄序號已經存在,添加失敗。");  
43.             return;  
44.         }  
45.   
46.         //插入到鏈表中, temp 的后面  
47.         // (注意,先連兩個節點之間的pre和next,再連另外兩個節點的pre和next,否則會出錯!!)  
48.         if (temp.getNext() != null) temp.getNext().setPre(h);  
49.         h.setNext(temp.getNext());//將h與temp的下一個節點相連(pre和next指針)  
50.   
51.         h.setPre(temp);  
52.         temp.setNext(h);//再將h與temp節點相連(pre和next指針)  
53.     }  
54.   
55.     //顯示鏈表(遍歷)  
56.     public void show() {  
57.         //判斷鏈表是否為空  
58.         if (head.getNext() == null) {  
59.             System.out.println("show():鏈表為空。。。。");  
60.             return;  
61.         }  
62.         //因為頭節點,不能動,因此我們需要一個輔助變量來遍歷  
63.         hero temp = head.getNext();  
64.         while (true) {  
65.             //判斷是否到鏈表最后  
66.             if (temp == null) {  
67.                 break;  
68.             }  
69.             //輸出節點的信息  
70.             System.out.println(temp.toString());  
71.             //將 temp 后移, 一定小心  
72.             temp = temp.getNext();  
73.         }  
74.     }  
75.   
76.     //修改節點的信息, 根據 no 編號來修改,即 no 編號不能改.  
77.     //說明  
78.     //1.  根據 newHeroNode  的 no 來修改即可  
79.     public void update(hero h) {  
80.         hero temp = head.getNext();//定義一個輔助變量  
81.         boolean flag = false;//表示是否找到該節點  
82.         //判斷鏈表是否空  
83.         if (head.getNext() == null) {  
84.             System.out.println("update():鏈表為空。。。。");  
85.             return;  
86.         }  
87.         //找到需要修改的節點, 根據 num值  
88.         while (true) {  
89.             if (temp == null) {  
90.                 break;//已經遍歷完鏈表  
91.             }  
92.             if (temp.getNum() == h.getNum()) {  
93.                 flag = true;  
94.                 break;  
95.             }  
96.             temp = temp.getNext();  
97.         }  
98.         if (flag) {  
99.             temp.setName(h.getName());  
100.             temp.setNikname(h.getNikname());  
101.         } else {//沒有找到  
102.             System.out.printf("沒有找到 編號 %d  的節點,不能修改\n", h.getNum());  
103.         }  
104.     }  
105.   
106.     //刪除節點  
107.     //思路  
108.     //1. head  不能動,因此我們需要一個 temp 輔助節點找到待刪除節點的前一個節點  
109.     //2. 雙向鏈表中我們在比較時,是 temp.no 和需要刪除的節點的 no 比較  
110.     public void delete(int n) {  
111.         if (head.getNext() == null) {  
112.             System.out.println("delete():鏈表為空。。。。");  
113.             return;  
114.         }  
115.         hero temp = head.getNext();// 輔助變量(指針)  
116.         boolean flag = false;// 標志是否找到待刪除節點的  
117.         while (true) {  
118.             if (temp == null) {//已經到鏈表的最后  
119.                 break;  
120.             }  
121.             if (temp.getNum() == n) {//找到的待刪除節點 temp  
122.                 flag = true;  
123.                 break;  
124.             }  
125.             temp = temp.getNext();//temp 后移,遍歷  
126.         }  
127.         if (flag) {  
128.             temp.getPre().setNext(temp.getNext());  
129.             if (temp.getNext() != null) {  
130.                 temp.getNext().setPre(temp.getPre());  
131.             }  
132.         } else {  
133.             System.out.printf("沒有找到 編號 %d  的節點,不能刪除\n", n);  
134.         }  
135.     }   
136. }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM