參考:
原文如下:
很多複雜點兒的問題都要用樹或圖來建模,樹和圖最基礎的操作是遍歷,但是有時候我們並不需要訪問每個結點。比如問你,中國地圖上有鎮江這個城市嗎?那你肯定是找到就立馬告訴我,而不會傻拉吧唧地把每個城市都看一遍,即使找到了鎮江也悶頭向前。在這裡我想為這一類問題提供乙個演算法的框架,降低思維複雜度。
當然圖的深度優先是基礎,我在這裡大概講一下,讀者有興趣可以去看《演算法導論》。圖是由結點和邊組成的,深度優先的思想就是如果通過當前訪問的結點還能跟蹤到未訪問的結點,那麼就繼續訪問,這也是「深度優先」這個名字的由來。按照這個描述,我們肯定要用變數來標識結點是否已經被訪問,《演算法導論》用三種顏色 ——
白色: 還沒被訪問;
灰色: 即將被訪問;
黑色: 已經訪問過了,並且由此結點所跟蹤到的結點也全都被訪問過了。
我們每次訪問乙個結點時都問自己,現在是個什麼狀況?通常有以下三種 ——
好的,我已經能解決這個問題了: ok,直接返回就可以了,因為已經找到答案了;
還不能作出任何判斷: 這樣的話我們只能繼續遍歷咯;
雖然還不能對結果作出明確的判斷,但是我們能確定後面結點無需再訪問:回溯,然後返回。
於是深度優先的框架就出來了:
#define white 0
#define gray 1
#define black 2
#define known 1 /* 已經能確定答案 */
#define unkown 2 /* 一無所知 */
#define cut 3 /* 能確定可以剪枝 */
void dfs(void)
/*
*要對每個結點都呼叫dfs_visit,
*這是為了處理非連通圖。
*如果你已經能確定圖是連通的,
*那麼只要對乙個結點呼叫dfs_visit就可以了
*/
for every white node v in graph
}
void dfs_visit(v) elseif (state==cut)
for every node u adjacent to v
color[v] = black;
// trace back
}
深度優先遍歷回溯演算法的應用
void search int cur 這個模板就是目前我遇見的最簡潔的模板,用乙個二維陣列vis 3 其中vis 0 i 表示列,vis 1 i 和vis 2 i 表示對角線。因為 x,y 的y x值標識了主對角線,x y值標識了副對角線。由於y x可能為負,所以訪問時要加上n。下面主要介紹一下主...
回溯法遵循深度優先嗎 深度優先搜尋(回溯法)
事實上,深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs即depth first search.其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次.舉例說明之 下圖是乙個無向圖,如果我們從a點發起深度優先搜尋 以下的訪問次序並不是唯一的,第二個點既可以是b也可以是c...
回溯和深度優先遍歷
回溯演算法思想如果在遞迴中使用其實就是深度優先遍歷。這是因為在遞迴呼叫中隱含著狀態的自動回退和恢復。就比如最經典的八皇后問題,說是用回溯演算法解決,但是實質上還是使用的深度優先遍歷。所以如果想學懂,第一步應該懂的是如何用遞迴解決問題。我們知道遞迴必須具備兩個條件,乙個是呼叫自己,乙個是有終止條件。這...