回溯法和樹的遍歷

2021-10-07 14:10:16 字數 1315 閱讀 1832

以下內容主要參考了嚴蔚敏版的資料結構教材。

回溯法是求解某些問題的全部或部分解的通用演算法,特別是帶有限制條件的問題。它通過不斷的產生問題的完整解的片段並不斷增長完整解的片段來獲取該問題的完整解。當發現某個完整解的片段不能生成最後的完整解時,就會丟棄所有以該片段解為基礎的完整解。

回溯法會首先列出完整解的片段的乙個集合。這個集合原則上可以通過不同的方式最後給出給定的問題的所有解。這是通過不斷地對該完整解的片段的集合中的片段解不斷擴充套件而達到的。

給出乙個簡單的例子。假設現在需要求集合a

=a=\

a=的冪集。集合a的冪集是由集合a的所有子集組成的集合。因此集合a的冪集中的元素是乙個集合,它或者是空集,或者含有集合a中的乙個元素或者含有集合a中的l兩個元素或者含有集合a中的三個元素。從集合a中的每乙個元素來看,它要麼屬於冪集中每乙個集合或者不屬於。求冪集中的每乙個集合可以看成是依次對集合a中的每乙個元素「取」或者「舍」的過程。如圖1所示。在圖1中除葉子節點之外的所有節點都可以看成是該問題完整解的片段,通過不斷取捨集合a中的元素來擴充套件該問題完整解的片段,當取捨完集合a中的所有元素時即得到了乙個該問題的完整解。

由此可看出求解問題的過程形成了一顆二叉樹,求解過程即為從根節點遞迴的先根遍歷該二叉樹。回溯法也是設計遞迴過程的一種重要方法,它的求解過程實質上是乙個先根遍歷一顆「狀態樹」的過程,只不過這棵樹不是遍歷前預先建立的,而是隱含在遍歷過程中。

}

//測試程式

intmain()

上面的例子是乙個特例。有些其他問題比如八皇后問題的求解過程的狀態樹不是一顆滿的多叉樹。當求解過程中的完整解的片段和問題所求解產生矛盾時(即該完整解的片段不能生成最後的完整解),不再繼續試探下去,這時出現的葉子節點不是該問題的完整解。這類問題的求解過程可以看成是在約束條件下進行先根遍歷,並在遍歷過程中刪去那些不滿足條件的分支。圖2是4皇后問題的狀態樹的部分。圖中打紅叉的是被刪去的分支。

資料結構 回溯法與樹的遍歷

回溯法求冪集 深度優先遍歷解空間 include include using namespace std void getpowerset const vector srcvec,vector dstvec,int i else int main 回溯法求解n皇后問題 include include...

回溯法解決馬步遍歷問題

設計一演算法,求解西洋棋中的馬的周遊問題 給定一8 8的棋盤,馬從棋盤的某個位置出發,經過棋盤中的每乙個方格恰好一次。只需求一可行解 一 演算法思想描述 指定乙個起點座標,從起點開始對每個點遍歷其能到達的八方向上的點,如果可以踩則走到該結點上,並繼續深入遍歷,直到最後走完所有的結點。二 完整的程式以...

排列組合(遍歷)回溯法

這裡有乙個回溯函式,使用第乙個整數的索引作為引數 backtrack first 1,如果第乙個整數有索引 n,意味著當前排列已完成。2,遍歷索引 first 到索引 n 1 的所有整數 則 在排列中放置第 i 個整數,即 swap nums first nums i 繼續生成從第 i 個整數開始的...