深度優先搜尋演算法

2021-08-19 18:43:22 字數 3045 閱讀 8588

1. 深度優先搜尋演算法的概念:

深度優先搜尋屬於圖演算法的一種,英文縮寫為dfs(depth first search.)其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個

節點只能訪問一次。如下例:

該圖為乙個無向圖,假設我們從a開始進行深度優先搜尋,第二點可以是b、c、d中任意乙個,假設訪問的是b,那麼路徑為a - b - e,搜尋完成後直接退回b,搜尋其下乙個子節點,完成b之後退到a,搜尋c節點,以此類推,直到找出需要的解。

dfs適合此類題目:給定初始狀態跟目標狀態,要求判斷從初始狀態到目標狀態是否有解。

深度優先搜尋(dfs)有兩個重要的點:第一是當前怎麼做,第二是下一步怎麼做;模板如下:

public static void dfs (int step) 

}

文字描述的內容比較簡單,網上搜尋一大堆,下面結合具體的例項來理解下深度優先搜尋演算法的精髓。

2.  例項:

例題1:將1-4,幾個數字進行全排列,列出所有的可能和個數。

解法一:最暴力的解法就是進行4重迴圈,然後判斷各個元素是否重複,不重複就是其中乙個解;如:1111,1112,1113....一直列到4444,取出所有不重複的解就是答案。**如下:

package dfs;

/** * 暴力全排0~4

* 思路:四個迴圈,從1開始到4結束.在這裡優化了一下,用陣列儲存,然後用另乙個陣列儲存結果,之後相加個數就可以知道有沒有數字重複。

* 因為對於全排,只有1,2,3,4僅且出現1次。

* * @author danqiusheng

*/public class normalfullv1

if(flag)}}

}}system.out.println("total count:"+count);}}

這段**中關鍵的難點在於判斷是否重複,其應用到的是陣列。新建乙個判斷重複的陣列result,其預設的陣列數都是0,將arr[i]作為其下標,若arr[i]相同,則result的陣列數是同乙個,將其進行自增,若存在重複的數即arr[i]肯定有相同的,那麼對result的其中乙個陣列數肯定大於1,從而進行重複的判斷;比如1123,其中1,1是重複的,即arr[1] 和 arr[2] 都是1,將其帶到result[arr[i]中,result[1]自增了兩次成為了2,大於1,存在重複。(注意**中的陣列都是從1開始迴圈的而不是0)

解法二,應用到深度優先搜尋演算法,先上**:

package dfs;

/** * 暴力全排0~4

* v3版本:遞迴時判斷當前數是否重複

* 邊界點:多少個排序數

* 重複內容:for迴圈

* * @author danqiusheng

*/public class normalfullv3

public static void full(int step)

// 重複內容

for (int i = 1; i < step_total; i++) }}

}

**最關鍵的部分是,重複部分的迴圈。將迴圈過的result[i]設定為1,來避免重複迴圈,即當arr[1] = 1時,arr[2]在迴圈時i = 1時不進行任何操作,繼續進行迴圈,當i = 2時,進行操作,並把2設定為不可用狀態,然後進行遞迴呼叫,直到滿足需求去執行full的第乙個if。結合前面的概念部分的圖表,第一層進入後依次進入後面的幾層,而不重複進入第一層(數字1,不會重複出現),直到把一條路徑上的走到盡頭,然後回到上乙個節點,走另外一條路到盡頭,知道遍歷完所有的節點。(遞迴呼叫的方式,這些步驟會被自動的實現)。

例題二:從v0出發,搜尋出一條長度為4的路徑;

* dfs核心偽**

* 前置條件是visit陣列全部設定成false

* @param n 當前開始搜尋的節點

* @param d 當前到達的深度,也即是路徑長度

* @return 是否有解

*/bool dfs(node n, int d)

for (node nextnode in n)

//重新設定成未訪問,因為它有可能出現在下一次搜尋的別的路徑中

visit[nextnode] = false;

} //到這裡,發現本次搜尋還沒找到解,那就要從當前節點的下乙個節點開始搜尋。

} return false;//本次搜尋無解

}練習:

一.  abc+def=ghi,數字1~9,不重複填入;

二. a + b/c + def/ghi = 10,條件同上;

(可以先自己完成,然後對照我做的)

package com.ncu.demo.test;

/** * 1-9任意乙個數字實現 abc + def = ghi; 列出實現的式子和個數

*/public class dfstest1

}//重複且不相等的生成arr

for (int i = 1; i < step_total; i++) }}

public static void main(string args)

}

package com.ncu.demo.test;

/** * a-i為1-9的代表,列出能實現 a + b/c + def/ghi = 10,的式子和個數

*/public class dfstest2

return;

}//遍歷實現1-9的賦值,不重複的最快速度

for (int i = 1; i < total_step; i++) }}

public static void main(string args)

}

深度優先搜尋演算法

include include define vertexnum 9 struct node typedef struct node graph struct node head vertexnum 定義圖形結構 int visited vertexnum 頂點陣列 深度優先搜尋 void dfs ...

深度優先搜尋演算法

今天我們來複習一下萬能的搜尋演算法之深度優先搜尋演算法。深度優先搜尋演算法顧名思義就是按照樹的延伸不停的往下搜尋,直到樹的盡頭之後再一步一步的回溯回來。好吧,我們直接問你乙個問題,給你乙個數n,讓你輸出從1到這個樹的全排列,你會怎麼寫,會不會想到去用若干個for迴圈?好吧,你肯定錯了,其實他考的就是...

深度優先搜尋演算法

題目要求 編寫乙個函式,傳入乙個int型陣列,返回該陣列能否分成兩組,使得兩組中各元素加起來的和相等,並且,所有5的倍數必須在其中乙個組中,所有3的倍數在另乙個組中 不包括5的倍數 能滿足以上條件,返回true 不滿足時返回false。這個題目 是考察 深度優先搜發演算法的。在需要讓arr3和arr...