dfs檢測有向圖是否存在環
阿新 • • 發佈:2022-03-09
【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 = nil16 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 break37 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部落格_判斷圖中是否有環