1. 程式人生 > 其它 >dfs檢測有向圖是否存在環

dfs檢測有向圖是否存在環

【lua實現】 

 1 local DfsCheckCycle = {}
 2 DfsCheckCycle.__index = DfsCheckCycle
 3 
 4 function DfsCheckCycle.new(g)
 5     local obj = {}
 6     setmetatable(obj, DfsCheckCycle)
 7 
 8     obj:ctor(g)
 9     return obj
10 end
11 
12 function DfsCheckCycle:ctor(g)
13     self.graph = g
14 
15     self.startVertex = nil
16 self.visited = nil 17 self.visitFromMap = nil 18 self.cycleCheckStack = nil ---每進1層遞迴設為true, 遞迴退出設為false 19 self.cyclePath = nil 20 end 21 22 function DfsCheckCycle:VisitAllReachable(startVertex) 23 self.startVertex = startVertex 24 self.visited = {} 25 self.visitFromMap = {}
26 self.cycleCheckStack = {} 27 self.cyclePath = nil 28 29 function dfs(v) 30 self.visited[v] = true 31 self.cycleCheckStack[v] = true 32 33 local list = self.graph:GetAdjacent(v) 34 for i=1,#list do 35 if self:HasCycle() then 36 break
37 end 38 39 local adjV = list[i] 40 if not self.visited[adjV] then 41 self.visitFromMap[adjV] = v 42 dfs(adjV) 43 return 44 end 45 46 if self.cycleCheckStack[adjV] then --發現環, adjV在前面的遞迴路徑上存在 47 self.cyclePath = {} 48 local cycleVertex = adjV 49 local tempV = v 50 while tempV ~= cycleVertex do --向前找到環的起點 51 table.insert(self.cyclePath, 1, tempV) 52 tempV = self.visitFromMap[tempV] 53 end 54 table.insert(self.cyclePath, 1, cycleVertex) --發生環的點 55 table.insert(self.cyclePath, cycleVertex) --回到環的起點 56 break 57 end 58 end 59 60 self.cycleCheckStack[v] = false 61 end 62 63 dfs(startVertex) 64 end 65 66 function DfsCheckCycle:HasCycle() 67 return nil ~= self.cyclePath 68 end 69 70 function DfsCheckCycle:PrintCyclePath() 71 if self:HasCycle() then 72 print(table.concat(self.cyclePath, "->")) 73 else 74 print("no cycle") 75 end 76 end

 

測試程式碼:

 1 function CreateDGraph3()
 2     local g = DGraph.new()
 3     g:AddVertex("0")
 4     g:AddVertex("1")
 5     g:AddVertex("2")
 6     g:AddVertex("3")
 7     g:AddVertex("4")
 8     g:AddVertex("5")
 9 
10     g:AddEdge("0", "1")
11     g:AddEdge("1", "2")
12     g:AddEdge("2", "3")
13     g:AddEdge("3", "1")
14     g:AddEdge("2", "4")
15     g:AddEdge("4", "5")
16 
17     tostring(g)
18     return g
19 end
20 
21 function DfsCheckCycleTest1()
22     local g = CreateDGraph3()
23     local dfsCheckCycle = DfsCheckCycle.new(g)
24     dfsCheckCycle:VisitAllReachable("0")
25     dfsCheckCycle:PrintCyclePath()
26 end
27 DfsCheckCycleTest1()

 

【參考】

環和有向無環圖

判斷圖中是否存在環_秦昊wan-CSDN部落格_判斷圖中是否有環