Ⅰ 什麼是深度優先搜索
深度優先搜索是一種在開發爬蟲早期使用較多的方法。它的目的是要達到被搜索結構的葉結點(即那些不包含任何超鏈的HTML文件) 。在一個HTML文件中,當一個超鏈被選擇後,被鏈接的HTML文件將執行深度優先搜索,即在搜索其餘的超鏈結果之前必須先完整地搜索單獨的一條鏈。深度優先搜索沿著HTML文件上的超鏈走到不能再深入為止,然後返回到某一個HTML文件,再繼續選擇該HTML文件中的其他超鏈。當不再有其他超鏈可選擇時,說明搜索已經結束.
事實上,深度優先搜索屬於圖演算法的一種,英文縮寫為DFS即Depth First Search.其過程簡要來說是對每一個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次.
在我們遇到的一些問題當中,有些問題我們不能夠確切的找出數學模型,即找不出一種直接求解的方法,解決這一類問題,我們一般採用搜索的方法解決。搜索就是用問題的所有可能去試探,按照一定的順序、規則,不斷去試探,直到找到問題的解,試完了也沒有找到解,那就是無解,試探時一定要試探完所有的情況(實際上就是窮舉); 對於問題的第一個狀態,叫初始狀態,要求的狀態叫目標狀態。 搜索就是把規則應用於實始狀態,在其產生的狀態中,直到得到一個目標狀態為止。 產生新的狀態的過程叫擴展(由一個狀態,應用規則,產生新狀態的過程) 搜索的要點:(1)初始狀態; (2)重復產生新狀態; (3)檢查新狀態是否為目標,是結束,否轉(2); 如果搜索是以接近起始狀態的程序依次擴展狀態的,叫寬度優先搜索。 如果擴展是首先擴展新產生的狀態,則叫深度優先搜索。 深度優先搜索 深度優先搜索用一個數組存放產生的所有狀態。 (1) 把初始狀態放入數組中,設為當前狀態; (2) 擴展當前的狀態,產生一個新的狀態放入數組中,同時把新產生的狀態設為當前狀態; (3) 判斷當前狀態是否和前面的重復,如果重復則回到上一個狀態,產生它的另一狀態; (4) 判斷當前狀態是否為目標狀態,如果是目標,則找到一個解答,結束演算法。 (5) 如果數組為空,說明無解。 對於pascal語言來講,它支持遞歸,在遞歸時可以自動實現回溯(利用局部變數)所以使用遞歸編寫深度優先搜索程序相對簡單,當然也有非遞歸實現的演算法。 搜索是人工智慧中的一種基本方法,是一項非常普遍使用的演算法策略,能夠解決許許多多的常見問題,在某些情況下我們很難想到高效的解法時,搜索往往是可選的唯一選擇。按照標準的話來講:搜索演算法是利用計算機的高性能來有目的的窮舉一個問題的部分或所有的可能情況,從而求出問題的解的一種方法。 搜索雖然簡單易學易於理解,但要掌握好並寫出速度快效率高優化好的程序卻又相當困難,總而言之,搜索演算法靈活多變,一般的框架很容易寫出,但合適的優化卻要根據實際情況來確定。在搜索演算法中,深度優先搜索(也可以稱為回溯法)是搜索演算法里最簡單也最常見的,今天我們就從這里講起,下面的內容假設讀者已經知道最基本的程序設計和簡單的遞歸演算法。
這是我找的資料,希望能幫到你~~
Ⅱ 簡述深度優先搜索遍歷的方法。
簡述深度優先搜索遍歷的方法?深度優先搜索演算法(Depth-First-Search, DFS),最初是一種用於遍歷或搜索樹和圖的演算法,在LeetCode中很常見,雖然感覺不難,但是理解起來還是有點難度的。
簡要概括,深度優先的主要思想就是「不撞南牆不回頭」,「一條路走到黑」,如果遇到「牆」或者「無路可走」時再去走下一條路。
思路
假如對樹進行遍歷,沿著樹的深度遍歷樹的節點,盡可能深的搜索樹的分支,當達到邊際時回溯上一個節點再進行搜索。如下圖的一個二叉樹。
首先給出這個二叉樹的深度優先遍歷的結果(假定先走左子樹):1->2->4->5->3->6->7
那是怎樣得到這樣的結果呢?
根據深度優先遍歷的概念:沿著這樹的某一分支向下遍歷到不能再深入為止,之後進行回溯再選定新的分支。
定義節點
class TreeNode{
int val;
TreeNode left;
TreeNode right;
}
遞歸的方式
分別對左右子樹進行遞歸,一直到底才進行回溯。如果不了解遞歸可以參考我的博客你真的懂遞歸嗎?。
class Solution{
public void (TreeNode root){
if(root == null){
return;
}
System.out.print(root.val +"->");
(root.left);
(root.right);
}
}
迭代的方式
上面實現了遞歸方式的深度優先遍歷,也可以利用棧把遞歸轉換為迭代的方式。
但是為了保證出棧的順序,需要先壓入右節點,再壓左節點。
class Solution{
public void (TreeNode root){
if(root == null) return;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
System.out.print(node.val + "->");
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
}
}
接著再列舉個利用深度優先遍歷的方式的題目
掃雷
給定一個表示游戲板的二維字元矩陣,'M'表示一個未挖出的地雷,'E'表示一個未挖出的空方塊,'B' 代表沒有相鄰(上,下,左,右,和所有4個對角線)地雷的已挖出的空白方塊,數字('1' 到 '8')表示有多少地雷與這塊已挖出的方塊相鄰,'X' 則表示一個已挖出的地雷。
根據以下規則,返回相應位置被點擊後對應的面板:
如果一個地雷('M')被挖出,游戲就結束了- 把它改為'X'。
如果一個沒有相鄰地雷的空方塊('E')被挖出,修改它為('B'),並且所有和其相鄰的方塊都應該被遞歸地揭露。
如果一個至少與一個地雷相鄰的空方塊('E')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量。
如果在此次點擊中,若無更多方塊可被揭露,則返回面板。
示例
輸入:
[['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'M', 'E', 'E'],
['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'E', 'E', 'E']]
Click : [3,0]
輸出:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
思路:根據給定的規則,當給定一個Click坐標,當不為雷的時候以此坐標為基點向四周8個方向進行深度遍歷,把空格E填充為B,並且把與地雷M相連的空方塊標記相鄰地雷的數量。
注意 :
在這個題中可以沿著8個方向遞歸遍歷,所有要注意程序中,採用了兩個for循環可以實現向8個方向遞歸。
Ⅲ 深度優先法(DFS)演算法
深度優先法:O(n+e)是指在圖形中,如果以頂點v作為起始開始查找,我們從頂點v的鄰接列表選擇一個未查找過的頂點w,由定點w繼續進行深度優先法的查找,沒查找一個頂點,便把該頂點存放在堆棧。知道查找到已經沒有任何鄰接未遍歷的頂點u,此時回到取出堆棧中的頂點,回到上一層頂點繼續查找未遍歷的頂點,知道所有的頂點皆查找過為止。over~!
Ⅳ 基本演算法——深度優先搜索(DFS)和廣度優先搜索(BFS)
深度優先搜索和廣度優先搜索,都是圖形搜索演算法,它兩相似,又卻不同,在應用上也被用到不同的地方。這里拿一起討論,方便比較。
一、深度優先搜索
深度優先搜索屬於圖演算法的一種,是一個針對圖和樹的遍歷演算法,英文縮寫為DFS即Depth First Search。深度優先搜索是圖論中的經典演算法,利用深度優先搜索演算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。一般用堆數據結構來輔助實現DFS演算法。其過程簡要來說是對每一個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。
基本步奏
(1)對於下面的樹而言,DFS方法首先從根節點1開始,其搜索節點順序是1,2,3,4,5,6,7,8(假定左分枝和右分枝中優先選擇左分枝)。
(2)從stack中訪問棧頂的點;
(3)找出與此點鄰接的且尚未遍歷的點,進行標記,然後放入stack中,依次進行;
(4)如果此點沒有尚未遍歷的鄰接點,則將此點從stack中彈出,再按照(3)依次進行;
(5)直到遍歷完整個樹,stack里的元素都將彈出,最後棧為空,DFS遍歷完成。
二、廣度優先搜索
廣度優先搜索(也稱寬度優先搜索,縮寫BFS,以下採用廣度來描述)是連通圖的一種遍歷演算法這一演算法也是很多重要的圖的演算法的原型。Dijkstra單源最短路徑演算法和Prim最小生成樹演算法都採用了和寬度優先搜索類似的思想。其別名又叫BFS,屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果為止。基本過程,BFS是從根節點開始,沿著樹(圖)的寬度遍歷樹(圖)的節點。如果所有節點均被訪問,則演算法中止。一般用隊列數據結構來輔助實現BFS演算法。
基本步奏
(1)給出一連通圖,如圖,初始化全是白色(未訪問);
(2)搜索起點V1(灰色);
(3)已搜索V1(黑色),即將搜索V2,V3,V4(標灰);
(4)對V2,V3,V4重復以上操作;
(5)直到終點V7被染灰,終止;
(6)最短路徑為V1,V4,V7.
Ⅳ 大數據最常用的演算法有哪些
奧地利符號計算研究所(Research Institute for Symbolic Computation,簡稱RISC)的Christoph Koutschan博士在自己的頁面上發布了一篇文章,提到他做了一個調查,參與者大多數是計算機科學家,他請這些科學家投票選出最重要的演算法,以下是這次調查的結果,按照英文名稱字母順序排序。
大數據等最核心的關鍵技術:32個演算法
1、A* 搜索演算法——圖形搜索演算法,從給定起點到給定終點計算出路徑。其中使用了一種啟發式的估算,為每個節點估算通過該節點的最佳路徑,並以之為各個地點排定次序。演算法以得到的次序訪問這些節點。因此,A*搜索演算法是最佳優先搜索的範例。
2、集束搜索(又名定向搜索,Beam Search)——最佳優先搜索演算法的優化。使用啟發式函數評估它檢查的每個節點的能力。不過,集束搜索只能在每個深度中發現最前面的m個最符合條件的節點,m是固定數字——集束的寬度。
3、二分查找(Binary Search)——在線性數組中找特定值的演算法,每個步驟去掉一半不符合要求的數據。
4、分支界定演算法(Branch and Bound)——在多種最優化問題中尋找特定最優化解決方案的演算法,特別是針對離散、組合的最優化。
5、Buchberger演算法——一種數學演算法,可將其視為針對單變數最大公約數求解的歐幾里得演算法和線性系統中高斯消元法的泛化。
6、數據壓縮——採取特定編碼方案,使用更少的位元組數(或是其他信息承載單元)對信息編碼的過程,又叫來源編碼。
7、Diffie-Hellman密鑰交換演算法——一種加密協議,允許雙方在事先不了解對方的情況下,在不安全的通信信道中,共同建立共享密鑰。該密鑰以後可與一個對稱密碼一起,加密後續通訊。
8、Dijkstra演算法——針對沒有負值權重邊的有向圖,計算其中的單一起點最短演算法。
9、離散微分演算法(Discrete differentiation)。
10、動態規劃演算法(Dynamic Programming)——展示互相覆蓋的子問題和最優子架構演算法
11、歐幾里得演算法(Euclidean algorithm)——計算兩個整數的最大公約數。最古老的演算法之一,出現在公元前300前歐幾里得的《幾何原本》。
12、期望-最大演算法(Expectation-maximization algorithm,又名EM-Training)——在統計計算中,期望-最大演算法在概率模型中尋找可能性最大的參數估算值,其中模型依賴於未發現的潛在變數。EM在兩個步驟中交替計算,第一步是計算期望,利用對隱藏變數的現有估計值,計算其最大可能估計值;第二步是最大化,最大化在第一步上求得的最大可能值來計算參數的值。
13、快速傅里葉變換(Fast Fourier transform,FFT)——計算離散的傅里葉變換(DFT)及其反轉。該演算法應用范圍很廣,從數字信號處理到解決偏微分方程,到快速計算大整數乘積。
14、梯度下降(Gradient descent)——一種數學上的最優化演算法。
15、哈希演算法(Hashing)。
16、堆排序(Heaps)。
17、Karatsuba乘法——需要完成上千位整數的乘法的系統中使用,比如計算機代數系統和大數程序庫,如果使用長乘法,速度太慢。該演算法發現於1962年。
18、LLL演算法(Lenstra-Lenstra-Lovasz lattice rection)——以格規約(lattice)基數為輸入,輸出短正交向量基數。LLL演算法在以下公共密鑰加密方法中有大量使用:背包加密系統(knapsack)、有特定設置的RSA加密等等。
19、最大流量演算法(Maximum flow)——該演算法試圖從一個流量網路中找到最大的流。它優勢被定義為找到這樣一個流的值。最大流問題可以看作更復雜的網路流問題的特定情況。最大流與網路中的界面有關,這就是最大流-最小截定理(Max-flow min-cut theorem)。Ford-Fulkerson 能找到一個流網路中的最大流。
20、合並排序(Merge Sort)。
21、牛頓法(Newton』s method)——求非線性方程(組)零點的一種重要的迭代法。
22、Q-learning學習演算法——這是一種通過學習動作值函數(action-value function)完成的強化學習演算法,函數採取在給定狀態的給定動作,並計算出期望的效用價值,在此後遵循固定的策略。Q-leanring的優勢是,在不需要環境模型的情況下,可以對比可採納行動的期望效用。
23、兩次篩法(Quadratic Sieve)——現代整數因子分解演算法,在實踐中,是目前已知第二快的此類演算法(僅次於數域篩法Number Field Sieve)。對於110位以下的十位整數,它仍是最快的,而且都認為它比數域篩法更簡單。
24、RANSAC——是「RANdom SAmple Consensus」的縮寫。該演算法根據一系列觀察得到的數據,數據中包含異常值,估算一個數學模型的參數值。其基本假設是:數據包含非異化值,也就是能夠通過某些模型參數解釋的值,異化值就是那些不符合模型的數據點。
25、RSA——公鑰加密演算法。首個適用於以簽名作為加密的演算法。RSA在電商行業中仍大規模使用,大家也相信它有足夠安全長度的公鑰。
26、Sch?nhage-Strassen演算法——在數學中,Sch?nhage-Strassen演算法是用來完成大整數的乘法的快速漸近演算法。其演算法復雜度為:O(N log(N) log(log(N))),該演算法使用了傅里葉變換。
27、單純型演算法(Simplex Algorithm)——在數學的優化理論中,單純型演算法是常用的技術,用來找到線性規劃問題的數值解。線性規劃問題包括在一組實變數上的一系列線性不等式組,以及一個等待最大化(或最小化)的固定線性函數。
28、奇異值分解(Singular value decomposition,簡稱SVD)——在線性代數中,SVD是重要的實數或復數矩陣的分解方法,在信號處理和統計中有多種應用,比如計算矩陣的偽逆矩陣(以求解最小二乘法問題)、解決超定線性系統(overdetermined linear systems)、矩陣逼近、數值天氣預報等等。
29、求解線性方程組(Solving a system of linear equations)——線性方程組是數學中最古老的問題,它們有很多應用,比如在數字信號處理、線性規劃中的估算和預測、數值分析中的非線性問題逼近等等。求解線性方程組,可以使用高斯—約當消去法(Gauss-Jordan elimination),或是柯列斯基分解( Cholesky decomposition)。
30、Strukturtensor演算法——應用於模式識別領域,為所有像素找出一種計算方法,看看該像素是否處於同質區域( homogenous region),看看它是否屬於邊緣,還是是一個頂點。
31、合並查找演算法(Union-find)——給定一組元素,該演算法常常用來把這些元素分為多個分離的、彼此不重合的組。不相交集(disjoint-set)的數據結構可以跟蹤這樣的切分方法。合並查找演算法可以在此種數據結構上完成兩個有用的操作:
查找:判斷某特定元素屬於哪個組。
合並:聯合或合並兩個組為一個組。
32、維特比演算法(Viterbi algorithm)——尋找隱藏狀態最有可能序列的動態規劃演算法,這種序列被稱為維特比路徑,其結果是一系列可以觀察到的事件,特別是在隱藏的Markov模型中。
以上就是Christoph博士對於最重要的演算法的調查結果。你們熟悉哪些演算法?又有哪些演算法是你們經常使用的?
Ⅵ 深度優先搜索演算法
這些書上都有很多例子的啊,你可以好好看看。
樹的特點,是兩個結點間都存著一個路徑,從每個結點都可以訪問到其它的結點。
一般對於樹進行深度優先演算法,是從根開始,依次訪問當前結點相鄰的一個結點。按深度遍歷,對於每一個結點都不重復的訪問到,直到所有結點被訪問。
如二叉樹,可以以先根遍歷來進行。當達到分枝結點沒有所要搜索的結果時,回溯到上一層結點,繼續選擇相鄰的路徑進行搜索,一直窮舉到結束,如果沒有找到,則是無解。
演算法很多,代碼就不寫了。思路明白了,怎麼寫都行。
Ⅶ 深度優先搜索的系統演算法
所有的搜索演算法從其最終的演算法實現上來看,都可以劃分成兩個部分──控制結構和產生系統。正如前面所說的,搜索演算法簡而言之就是窮舉所有可能情況並找到合適的答案,所以最基本的問題就是羅列出所有可能的情況,這其實就是一種產生式系統。
我們將所要解答的問題劃分成若干個階段或者步驟,當一個階段計算完畢,下面往往有多種可選選擇,所有的選擇共同組成了問題的解空間,對搜索演算法而言,將所有的階段或步驟畫出來就類似是樹的結構(如圖)。
從根開始計算,到找到位於某個節點的解,回溯法(深度優先搜索)作為最基本的搜索演算法,其採用了一種「一隻向下走,走不通就掉頭」的思想(體會「回溯」二字),相當於採用了先根遍歷的方法來構造搜索樹。
上面的話可能難於理解,沒關系,我們通過基本框架和例子來闡述這個演算法,你會發現其中的原理非常簡單自然。
Ⅷ 深度優先搜索和廣度優先搜索、A星演算法三種演算法的區別和聯系
1、何謂啟發式搜索演算法
在說它之前先提提狀態空間搜索.狀態空間搜索,如果按專業點的說法就是將問題求解過程表現為從初始狀態到目標狀態尋找這個路徑的過程.通俗點說,就是 在解一個問題時,找到一條解題的過程可以從求解的開始到問題的結果(好象並不通俗哦).由於求解問題的過程中分枝有很多,定性,不完備性造成的,使得求解的路徑很多這就構成了一個圖,我們說這個圖就是狀態空間.問題的求解實際上就是在這個圖中找到一條路徑可以從開始到結果.這個尋找的過程就是狀態空間搜索.
常用的狀態空間搜索有深度優先和廣度優先.廣度優先是從初始狀態一層一層向下找,直到找到目標為止.深度優先是按照一定的順序前查找完一個分支,再查找另一個分支,以至找到目標為止.這兩種演算法在數據結構書中都有描述,可以參看這些書得到更詳細的解釋.
前面說的廣度和深度優先搜索有一個很大的缺陷就是他們都是在一個給定的狀態空間中窮舉.這在狀態空間不大的情況下是很合適的演算法,可是當狀態空間十分大,且不預測的情況下就不可取了.他的效率實在太低,甚至不可完成.在這里就要用到啟發式搜索了.
啟發式搜索就是在狀態空間中的搜索對每一個搜索的位置進行評估,得到最好的位置,再從這個位置進行搜索直到目標.這樣可以省略大量無畏的搜索路徑,提 到了效率.在啟發式搜索中,對位置的估價是十分重要的.採用了不同的估價可以有不同的效果.我們先看看估價是如何表示的.
啟發中的估價是用估價函數表示的,如:
f(n) = g(n) + h(n)
其中f(n) 是節點n的估價函數,g(n)實在狀態空間中從初始節點到n節點的實際代價,h(n)是從n到目標節點最佳路徑的估計代價.在這里主要是h(n)體現了搜 索的啟發信息,因為g(n)是已知的.如果說詳細點,g(n)代表了搜索的廣度的優先趨勢.但是當h(n) >> g(n)時,可以省略g(n),而提高效率.這些就深了,不懂也不影響啦!我們繼續看看何謂A*演算法.
2、初識A*演算法
啟發式搜索其實有很多的演算法,比如:局部擇優搜索法、最好優先搜索法等等.當然A*也是.這些演算法都使用了啟發函數,但在具體的選取最佳搜索節點時的 策略不同.象局部擇優搜索法,就是在搜索的過程中選取「最佳節點」後舍棄其他的兄弟節點,父親節點,而一直得搜索下去.這種搜索的結果很明顯,由於舍棄了 其他的節點,可能也把最好的節點都舍棄了,因為求解的最佳節點只是在該階段的最佳並不一定是全局的最佳.最好優先就聰明多了,他在搜索時,便沒有舍棄節點 (除非該節點是死節點),在每一步的估價中都把當前的節點和以前的節點的估價值比較得到一個「最佳的節點」.這樣可以有效的防止「最佳節點」的丟失.那麼 A*演算法又是一種什麼樣的演算法呢?其實A*演算法也是一種最好優先的演算法.只不過要加上一些約束條件罷了.由於在一些問題求解時,我們希望能夠求解出狀態空 間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性.A* 演算法是一個可採納的最好優先演算法.A*演算法的估價函數可表示為:
f'(n) = g'(n) + h'(n)
這里,f'(n)是估價函數,g'(n)是起點到終點的最短路徑值,h'(n)是n到目標的最斷路經的啟發值.由於這個f'(n)其實是無法預先知道 的,所以我們用前面的估價函數f(n)做近似.g(n)代替g'(n),但 g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)
Ⅸ DFS(深搜)演算法
深度優先搜索演算法(Depth-First-Search) :是一種用於遍歷或搜索樹或圖的演算法。 沿著樹的深度遍歷樹的節點,盡可能深的搜索樹的分支。當節點v的所在邊都己被探尋過或者在搜尋時結點不滿足條件,搜索將回溯到發現節點v的那條邊的起始節點。整個進程反復進行直到所有節點都被訪問為止。
話說大詩人李白,一生好飲。幸好他從不開車。
一天,他提著酒壺,從家裡出來,酒壺中有酒2斗。他邊走邊唱:
無事街上走,提壺去打酒。
逢店加一倍,遇花喝一斗。
這一路上,他一共遇到店5次,遇到花10次,已知最後一次遇到的是花,他正好把酒喝光了。
請你計算李白遇到店和花的次序,可以把遇店記為a,遇花記為b。則:babaabbabbabbbb 就是合理的次序。像這樣的答案一共有多少呢?請你計算出所有可能方案的個數(包含題目給出的)。
注意:通過瀏覽器提交答案。答案是個整數。不要書寫任何多餘的內容。
答案:14
小明剛剛看完電影《第39級台階》,離開電影院的時候,他數了數禮堂前的台階數,恰好是39級!
站在台階前,他突然又想著一個問題:
如果我每一步只能邁上1個或2個台階。先邁左腳,然後左右交替,最後一步是邁右腳,也就是說一共要走偶數步。那麼,上完39級台階,有多少種不同的上法呢?
請你利用計算機的優勢,幫助小明尋找答案。
要求提交的是一個整數。
注意:不要提交解答過程,或其它的輔助說明文字。
Ⅹ 深度優先搜索和廣度優先搜索的區別。 請講的詳細點,最好能用例子,謝謝啦
深度優先搜索所遵循的搜索策略是盡可能「深」地搜索圖。在深度優先搜索中,對於最新發現的結點,如果它還有以此為起點而未搜過的邊,就沿著邊繼續搜索下去。當結點v的所有邊都已被探尋過,搜索將回溯到發現結點v有那條邊的始結點。這一過程一直進行到已發現從源結點可達的所有結點為止。如果還存在未被發現的結點,則選擇其中一個作為源結點並重復以上過程,整個過程反復進行直到所有結點都被發現為止。
深度優先搜索基本演算法如下{遞歸演算法}:
PROCEDURE dfs_try(i);
FOR i:=1 to maxr DO
BEGIN
IF 子結點 mr 符合條件 THEN
BEGIN
產生的子結點mr入棧;
IF 子結點mr是目標結點
THEN 輸出
ELSE dfs_try(i+1);
棧頂元素出棧;
END;
END; 寬度優先搜索演算法(又稱廣度優先搜索演算法)是最簡單的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型。Dijksta單源最短路徑演算法和Prim最小生成樹演算法都採用了與寬度優先搜索類似的思想。
寬度優先搜索的核心思想是:從初始結點開始,應用算符生成第一層結點,檢查目標結點是否在這些後繼結點中,若沒有,再用產生式規則將所有第一層的結點逐一擴展,得到第二層結點,並逐一檢查第二層結點中是否包含目標結點。若沒有,再用算符逐一擴展第二層所有結點……,如此依次擴展,直到發現目標結點為止。
寬度優先搜索基本演算法如下:
list[1]:=source; {加入初始結點,list為待擴展結點的表}
head:=0; {隊首指針}
foot:=1; {隊尾指針}
REPEAT
head:=head+1;
FOR x:=1 to 規則數 DO
BEGIN
根據規則產生新結點nw;
IF not_appear(nw,list) THEN {若新結點隊列中不存在,則加到隊尾}
BEGIN
foot:=foot+1;
list[foot]:=nw;
list[foot].father:=head;
IF list[foot]=目標結點 THEN 輸出;
END;
END;
UNTIL head>foot; {隊列為空表明再無結點可擴展}
望採納