无权图深度,广度优先搜索

# 无权无向图,无权有向图都可以

# dfs和bfs都可以知道是否可达

# dfs和bfs都可以获取两点之间的路径, 但bfs的路径是最短路径

 

【深度优先搜索bfs】

 1 local Dfs = {}
 2 Dfs.__index = Dfs
 3 
 4 function Dfs.new(g)
 5     local obj = {}
 6     setmetatable(obj, Dfs)
 7 
 8     obj:ctor(g)
 9     return obj
10 end
11 
12 function Dfs:ctor(g)
13     if nil == g then
14         print("ctor g nil")
15     end
16     self.graph = g
17     self.startVertex = nil
18     self.visited = {}
19     self.visitFromMap = {} --通过目标点获取访问源点
20 end
21 
22 ---到另一个点是否可达
23 function Dfs:IsReachable(endVertex)
24     return true == self.visited[endVertex]
25 end
26 
27 ---遍历所有可达的顶点
28 function Dfs:VisitAllReachable(startVertex)
29     self.startVertex = startVertex
30     self.visited = {}
31     self.visitFromMap = {}
32 
33     function dfs(v)
34         self.visited[v] = true
35 
36         local list = self.graph:GetAdjacent(v)
37         for i=1,#list do
38             local adjV = list[i]
39             if not self.visited[adjV] then
40                 self.visitFromMap[adjV] = v
41                 dfs(adjV)
42             end
43         end
44     end
45 
46     dfs(startVertex)
47 end
48 
49 ---两个点之间的路径
50 function Dfs:GetPath(endVertex)
51     if not self:IsReachable(endVertex) then return nil end
52 
53     local pathQueue = {}
54     --从目标点, 反向一步一步算出起点
55     local v = endVertex
56     while v ~= self.startVertex do
57         table.insert(pathQueue, 1, v)
58         v = self.visitFromMap[v]
59     end
60     table.insert(pathQueue, 1, v)
61     return pathQueue
62 end

测试代码:

1 function TestDfs1()
2     local g = CreateDGraph()
3     local dfs = Dfs.new(g)
4     dfs:VisitAllReachable("3")
5     print(dfs:IsReachable("4"))
6     print(dfs:IsReachable("0"))
7     print(table.concat(dfs:GetPath("4"), "->"))
8 end
9 TestDfs1()

 

【广度优先搜索bfs】

 1 local Bfs = {}
 2 Bfs.__index = Bfs
 3 
 4 function Bfs.new(g)
 5     local obj = {}
 6     setmetatable(obj, Bfs)
 7 
 8     obj:ctor(g)
 9     return obj
10 end
11 
12 function Bfs:ctor(g)
13     self.graph = g
14     self.startVertex = nil
15     self.visited = {}
16     self.visitFrom = {} --从哪个点访问的key对应的点
17 end
18 
19 function Bfs:IsReachable(endVertex)
20     return true == self.visited[endVertex]
21 end
22 
23 function Bfs:VisitAllReachable(startVertex)
24     self.startVertex = startVertex
25     self.visited = {}
26     self.visitFrom = {}
27 
28     local queue = {}
29     self.visited[startVertex] = true
30     table.insert(queue, startVertex)
31 
32     while #queue > 0 do
33         local v = queue[1]
34         table.remove(queue, 1)
35 
36         local list = self.graph:GetAdjacent(v)
37         for i=1,#list do
38             local adjV = list[i]
39             if not self.visited[adjV] then
40                 self.visitFrom[adjV] = v
41                 self.visited[adjV] = true
42                 table.insert(queue, adjV)
43             end
44         end
45     end
46 end
47 
48 function Bfs:GetPath(endVertex)
49     if not self:IsReachable(endVertex) then return nil end
50 
51     local pathQueue = {}
52     local v = endVertex
53     while v ~= self.startVertex do
54         table.insert(pathQueue, 1, v)
55         v = self.visitFrom[v]
56     end
57     table.insert(pathQueue, 1, v)
58     return pathQueue
59 end

测试代码:

 1 function CreateDGraph2()
 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", "2")
11     g:AddEdge("2", "0")
12     g:AddEdge("2", "1")
13     g:AddEdge("2", "3")
14     g:AddEdge("2", "5")
15     g:AddEdge("3", "2")
16     g:AddEdge("3", "4")
17     g:AddEdge("3", "5")
18 
19     return g
20 end
21 
22 function TestBfs1()
23     local g = CreateDGraph2()
24 
25     local dfs = Bfs.new(g)
26     dfs:VisitAllReachable("0")
27     print(dfs:IsReachable("3"))
28     print(dfs:IsReachable("5"))
29     print(table.concat(dfs:GetPath("5"), "->"))
30 end
31 TestBfs1()

 

【参考】

图论算法——有向图的可达性与寻路_日积月累,天道酬勤-CSDN博客_图可达算法

 

posted @ 2022-03-10 23:33  yanghui01  阅读(19)  评论(0编辑  收藏  举报