防禦性程式設計習慣
程式員在編寫代碼的時候,預料有可能出現問題的地方或者點,然後為這些隐患提前制定預防方案或者措施,比如資料庫發生異常之後的復原,打開某些資源之前,判斷圖檔是否存在,網絡斷開之後的重連次數或者是否連接配接備用網絡,除法運算中的除數問題,函數或者類在接受資料的時候的過濾情況,比如如果輸入一個指針參數,是否需要判斷是不是空指針?輸入一個字元串參數,是否需要判斷字元串空否……總的來說就是防止出現不可預見的事情,設計出魯棒性的代碼。
看下面的例子
輸入一個連結清單,輸對外連結表中倒數第 m 個結點額内容,要求從1開始計數,也就是說,連結清單的尾結點是倒數第一個結點,例如連結清單一共有6個結點,從頭結點開始:1、2、3、4、5、6.連結清單的倒數第三個結點的值為4。
思考:
1、最直接的思路就是從連結清單的末尾開始,回溯到第 m 個結點,但是給出的連結清單結構裡這是單連結清單,而單連結清單的 next 指針是從前到後指向的,這個思路是非常不友善的,可以說行不通。
2、那麼逆向的不行,就看看正向的,可以把求倒數第 m 個結點轉換為求正數第 x 個結點的問題,假設連結清單有 n 個結點,那麼倒數第 m 個結點就是從頭開始的正數第 n-m+1個結點,也就是說,知道了表長,然後通過 n-m+1這個資料,就能找到倒數第 m 個結點的位置。也就是需要從頭到尾周遊連結清單,求出表長 n,然後再從頭到尾周遊連結清單,找到 n-m+1個位置即可。代碼很容易寫出,但是并不是最好的解法。
繼續分析第2個思路,求得改進
原思路是需要周遊兩次連結清單的,顯然有些臃腫了,那麼如果就要求隻周遊一次連結清單就能實作上述要求,就需要思考下改進方法。那就一次定義兩個訓示指針,讓第一個指針和第二個指針的距離相差 m-1個結點就行了,這樣,兩個指針同步走,當第一個指針走到最後一個結點的時候,第二個指針剛剛走到倒數第 m 個結點的位置。

代碼如下:
繼續分析第二個思路,測試代碼的魯棒性
第一、貌似程式的開始,并沒有進行判空操作,如果傳入的是空連結清單,也就是 head 是 null 指針,如果繼續運作,那麼代碼通路了空指針指向的記憶體,程式就會發生奔潰。
第二、如果連結清單的長度 n 比 m 還要小,這樣肯定不符合邏輯,需要提前判斷和預防(防禦性的程式設計習慣),因為程式裡有 for 循環,第一個指針會先走 m-1步,如果n 比 m 小,那麼for 循環那裡肯定出錯,仍是空指針的問題。
第三,這裡的函數形參裡的 m,聲明的是 int 類型,如果聲明為了無符号 unsigned int 類型,顯然,在fou 循環裡,m-1語句有風險!如果 m 本身就是0,則 m-1為-1,類型轉換為無符号數,反正肯定不是-1。是以 for 循環的次數不是我們想要的結果。同樣程式出現崩虧。
改進的建議
1、如果輸入的連結清單為空表,那麼程式直接傳回 null 處理
2、如果連結清單程度 n 比 m 小,那麼在for 循環語句裡,需要if判斷一下,檢視何時出現 next 等于 null的時候,提前避免空指針錯誤。
3、對于輸入0,代碼中函數參數寫的是 int 類型,雖然無礙,但是實際上,求倒數第0個結點是沒有意義的,因為假定是從1開始的,那麼此時也可以傳回 null
繼續分析,提煉思想
比如有問題:求連結清單的中間結點,如果連結清單結點 n 為奇數,就是傳回中間結點,如果結點n 是偶數,那就傳回中間結點兩個之間的任意一個結點。
題目是讓求中間結點的,那麼可以周遊整個連結清單,求得長度 n,然後判斷奇偶性,求得中間結點。其實按照上題的思想,本題同樣可以定義兩個指針,同時從連結清單的頭結點出發,同步移動,第一個指針 a一次走一步,第二個指針b一次走兩步,當走的快的指針到末位結點的時候,走的慢的指針剛剛處在中間位置,(因為a 每次移動都比 b 快1步,而 a 每次走2步,走到了末位的時候,b 其實剛剛走了一半的路程)省去了求n 和判斷與計算的過程。
比如一個問題:判斷一個單連結清單是否有環?
思考
有環,說明連結清單如果一直周遊下去,會回到出發位置。同樣,還是定義兩個指針,同時從頭結點出發,一個指針a一次走一步,另一個指針b一次走兩步,如果走的快的b指針反而還追上了走得慢的 a 指針(b 每次兩步,如果走到了末位,那麼 a 才走到中間,b 繼續走就回到了出發點,此時 b 和 a 相距一半的路程,那麼 b 繼續走,一定會追上 a,且是在起點位置),此時說明連結清單有環存在,如果走的快的指針走了兩圈都沒有追上走的慢的a 指針,說明連結清單沒有環結構。
小結:
當處理連結清單問題的時候,一個訓示指針解決不了問題,可以嘗試使用兩個訓示指針,一個走的快點,一個走的慢點,随機應變是同步還是說等待哪個先走,這樣可以另辟蹊徑去解決問題。
辛苦的勞動,轉載請注明出處,謝謝……
http://www.cnblogs.com/kubixuesheng/p/4391357.html