上一節說了遞迴控制,最後分析了遞迴函式的缺點,我們現在使用迴圈控制將遞迴函式進行改造,使stack的壓力減小,提高程式的執行效率。
迴圈不變式是一句斷言定義各變數所需滿足的條件,在寫迴圈控制的時候需要重點思考,這麼說太抽象,具體看後面例題~
把問題切開,假設一部分已經完成,一部分未完成,思考下一步如何往前推進。
例子1:鍊錶反轉
上節中的鍊錶反轉使用遞迴實現,假設鍊錶有一萬活著更多元素,執行起來效率極低,而且還有stackoverflow的問題,使用迴圈實現,效率很高。
思路分析如圖:
我們將鍊錶邏輯分開,假設鍊錶左邊已經完成了反轉,右邊沒有完成反轉,那麼只需要思考下一步我怎麼把值為3的這個節點反轉,我們只需要將currenthead節點指向newhead節點,並將currenthead節點和newhead向後移動即可。完成後,在判斷一些邊界條件,在while迴圈中思考如何去除邊界條件和退出迴圈。我們具體看**分析:
public
class linkedlistreverser
//loop invariant holds.
return newhead;}}
例子2:刪除鍊錶中的某個元素題目如圖:
我們現在要把鍊錶中的節點值為2的節點刪除,思路不變,首先假設左邊某部分的鍊錶意見刪除完畢(比如3節點旁邊的2),下面思考如何刪除右邊部分的節點,我們首先需要判斷3右邊的節點是否為2,若是,則將指標指向下乙個節點,這樣就實現了刪除該節點,如果3右邊節點不是2,next直接指向右邊的節點即可。需要思考的是一些邊界條件,比如鍊錶為空,或者鍊錶第乙個節點就為要刪除的元素等等,使用while、if迴圈處理邊界情況。**實現如下:
public
class linkedlistdeletor
if (head==null)
node prev = head;
//loop invariant:list nodes from head up to prev has been
//processed.(nodes with values equals to value are deleted)
while (prev.getnext()!=null) else
}return head;}}
只要明確了迴圈不變式,了解了邊界條件,寫乙個迴圈控制的程式也就不難了,而且迴圈控制有很多好處,但是迴圈函式也不是萬能的,很多問題無法解決,需要我們具體問題具體分析。下一節是一些關於邊界控制的考慮問題。
ps:本打算每天(至少2天)就更新的,結果實驗室來個個臨時專案,估計要花點時間了~
Python程式設計思想(12) for in迴圈
python程式設計思想 專欄 目錄 1.for in迴圈的基礎知識 2.用for in迴圈變數元組和列表 3.用for in迴圈遍歷字典 4.統計列表中單詞的出現次數 for in迴圈可以用於遍歷範圍 列表 元素和字典等可迭代物件包含的元素。for in迴圈的語法格式如下 for 變數 in 字串...
c 程式設計中的除錯技巧 C 程式設計思想
1.除錯標記 適用預處理 define定義乙個或多個除錯標記,在 中把除錯部分使用 ifdef 和 endif 進行管理。當程式最終除錯完成後,只需要使用 undef標記,除錯 就會消失。常用的除錯標記為debug,語句序列 define debug ifdef debug 除錯 endif 2.執...
Python程式設計思想(13) 迴圈中的else語句
python程式設計思想 專欄 python的迴圈都可以定義else 塊,當迴圈條件為 false時,程式會執行else 塊,通常在else子句中完成迴圈的收尾工作。下面的 演示了 while迴圈中else子句的使用方法。示例 while else.py count 0 while count 10...