雙向鏈表(double linked list)是在單鏈表的每一個結點中,再設置一個指向其前驅結點的指針域。結點都有兩個指針域,一個指向直接後繼,另外一個指向直接前驅。php
如今分析添加的狀況
已經有1號英雄和5號英雄,如今要添加3號英雄
此時cur指向了1號英雄,hero指向3號英雄
cur指向1號英雄,發現cur的下一個是5號英雄,大於要添加的3號英雄
分析圖
過程優化
(1)讓3號英雄指向5號英雄,即把這個①號線搭起來
$hero->next=$cur->next;
//$cur指向1號英雄,$cur->next指向5號英雄
(2)而後再搭pre這根線,讓3號英雄的pre指向1號英雄,即把這個②號線搭起來
$hero->per=$cur;
(3)而後讓5號英雄的pre指向3號英雄,即把這個③號線搭起來
$cur->next->pre=$hero;
//$cur->next指向5號英雄,$cur->next->pre爲5號英雄指向1號英雄,即圖中⑥號線
//此時⑥號線就斷掉了,原來的5號英雄的pre是指向1號英雄的,如今指向了3號英雄
(4)讓1號英雄指向3號英雄,即把這個④號線搭起來
$cur->next=$hero;
//此時⑤號線就斷掉了,原來的$cur->next是指向5號英雄的,如今指向了3號英雄指針
改進:不嚴密的地方,能夠和前面的進行合併的
添加英雄,把添加時是空鏈表和不是空鏈表的狀況,合併到一塊兒了
如今考慮:要添加的人就在末尾
有一個head和1號人物,要添加的是6號人物
此時cur指向1號人物,
當按照原先的代碼執行,既下面這段代碼,會有一些小問題的
$hero->next=$cur->next;
$hero->pre=$cur;
$cur->next->pre=$hero;
$cur->next=$hero;
執行
(1)$hero->next=$cur->next;
此時cur指向1號人物,1號人物此時是最後的一個節點,$cur->next就是空了,那麼$hero->next=$cur->next; 此時這句話就沒有意義了,由於$hero->next自己就是空啊,你再賦給它空,沒有意義,乾脆這句話此時就不執行了。因此要加一個一個判斷條件,即$cur->next不等於空,執行$hero->next=$cur->next; 纔有價值
if($cur->next!=null){
$hero->next=$cur->next;
}
(2)$hero->pre=$cur;
這句話仍是頗有價值的,以下圖所示,把①號線搭起來了
(3)$cur->next->pre=$hero;
此時cur指向1號人物,$cur->next就是空了,空的pre就沒意義了,全部也要和上面的(1)同樣,加判斷
if($cur->next!=null){
$cur->next->pre=$hero;
}
(4)$cur->next=$hero;
這句是有意義的,以下圖所示,把②號線搭起來了
若是前面的代碼修改爲了以下的代碼:
if($cur->next!=null){
$hero->next=$cur->next;
}
$hero->pre=$cur;
if($cur->next!=null){
$cur->next->pre=$hero;
}
$cur->next=$hero;
就和前面的一個if判斷語句不謀而合了blog
即在doubleLink.php中的這段代碼
if($cur->next==null){ //若是是,就說明是空鏈表,添加第一個英雄
$cur->next=$hero;
//這樣就首尾相連了
$hero->pre=$cur;
}else{...
都是在說當$cur->next爲空的時候,就執行
$cur->next=$hero;
$hero->pre=$cur;博客
代碼不是一步到位的,優化前進im
======
此時刪除英雄就不須要輔助節點了
分析圖
當要刪除的節點在最後的時候,還須要判斷下
此時$cur->next自己就是空了,全部要加判斷了
$cur->pre->next=$cur->next; //這個就至關於把1號節點的next置空了,這個沒錯
因此要這樣:
if($cur->next!=null){
$cur->next->pre=$cur->pre;
}
$cur->pre->next=$cur->next;
這樣執行的話,把上圖中的藍線就去掉了,這樣6號英雄就訪問不到了,6號英雄出列了,由於咱們是從表頭開始找的,$cur-next就訪問不到6號英雄節點了,6號英雄指向別人是沒有用的,★關鍵★是沒有人指向它。鏈表