无向图-邻接表方式

【理论知识可以参考这边】

图论算法——无向图的邻接链表实现_日积月累,天道酬勤-CSDN博客_无向图的邻接链表

图论算法——无向图的深度优先搜索和广度优先搜索_日积月累,天道酬勤-CSDN博客

漫画:图的 “最短路径” 问题_程序员小灰的博客-CSDN博客

 

【lua实现】

 1 local Graph = {}
 2 Graph.__index = Graph
 3 
 4 ---无向图
 5 function Graph.new()
 6     local obj = {}
 7     setmetatable(obj, Graph)
 8 
 9     obj:ctor()
10     return obj
11 end
12 
13 function Graph:ctor()
14     self.adjacent = {}
15     self.edgeCount = 0
16     self.vertexList = {}
17 end
18 
19 function Graph:GetVertexCount()
20     return #self.vertexList
21 end
22 
23 function Graph:GetVertex(index)
24     return self.vertexList[index]
25 end
26 
27 function Graph:GetEdgeCount()
28     return self.edgeCount
29 end
30 
31 function Graph:AddVertex(v)
32     local list = self.adjacent[v]
33     if nil == list then
34         list = {}
35         self.adjacent[v] = list
36         table.insert(self.vertexList, v)
37     else
38         --顶点已存在
39     end
40 end
41 
42 function Graph:AddEdge(v1, v2)
43     local list1 = self.adjacent[v1]
44     local list2 = self.adjacent[v2]
45     if nil == list1 or nil == list2 then
46         return --顶点不存在
47     end
48 
49     table.insert(list1, v2) --最好判断下在list中是否已存在
50     table.insert(list2, v1)
51     self.edgeCount = self.edgeCount + 1
52 end
53 
54 function Graph:GetAdjacent(v)
55     return self.adjacent[v]
56 end
57 
58 function Graph:__tostring()
59     print("-----Graph")
60     for i=1,#self.vertexList do
61         local v = self.vertexList[i]
62         local adjList = self.adjacent[v]
63         print(v, "-->", table.concat(adjList, ", "))
64     end
65     print("-----")
66 end
67 
68 return Graph

 

测试代码:

 1 function CreateGraph()
 2     local g = Graph.new()
 3     g:AddVertex("A")
 4     g:AddVertex("B")
 5     g:AddVertex("C")
 6     g:AddVertex("D")
 7     g:AddVertex("E")
 8     g:AddVertex("F")
 9     g:AddVertex("G")
10 
11     g:AddEdge("A", "B")
12     g:AddEdge("A", "C")
13     g:AddEdge("B", "D")
14     g:AddEdge("B", "E")
15     g:AddEdge("C", "D")
16     g:AddEdge("C", "F")
17     g:AddEdge("D", "E")
18     g:AddEdge("D", "F")
19     g:AddEdge("E", "G")
20     g:AddEdge("F", "G")
21 
22     print("v ct: ", g:GetVertexCount())
23     print("edge ct:", g:GetEdgeCount())
24     tostring(g)
25     return g
26 end

上面的代码会创建出这样一张图

 

 

 

 

【深度优先搜索】

# 这边使用了递归来实现

# 用途:会把某个点的所有可达顶点都走一遍,即可以通过它来确定两个点之间是否可达

 1 function TestDfs1()
 2     local visited = {}
 3 
 4     function Dfs1(g, vertex)
 5         print(vertex)
 6 
 7         visited[vertex] = true
 8         local list = g:GetAdjacent(vertex)
 9         for i=1,#list do
10             local adjV = list[i]
11             if not visited[adjV] then
12                 Dfs1(g, adjV)
13             end
14         end
15     end
16 
17     local g = CreateGraph()
18     Dfs1(g, "A")
19 end
20 TestDfs1()

 

【广度优先搜索】

# 一般会借助一个队列来实现

# 用途1:会把某个点的所有可达顶点都走一遍,即可以知道两个点之间是否可达

# 用途2:可以算出点A到点B的最短路径 

 1 function TestBfs1()
 2     local edgeFrom = {}
 3 
 4     function Bfs1(g, vertex)
 5         local visited = {}
 6         local queue = {}
 7         visited[vertex] = true --加入queue就要设为visited
 8         table.insert(queue, vertex)
 9 
10         while #queue > 0 do
11             local v = queue[1]
12             print("---", table.concat(queue, ", "))
13             print(v)
14             table.remove(queue, 1)
15 
16             local list = g:GetAdjacent(v)
17             for i=1,#list do
18                 local adjV = list[i]
19                 if not visited[adjV] then
20                     visited[adjV] = true --加入queue就要设为visited
21                     edgeFrom[adjV] = v
22                     table.insert(queue, adjV)
23                 end
24             end
25         end
26     end
27 
28     local g = CreateGraph()
29     Bfs1(g, "A")
30 
31     local path = {}
32     local target = "G"
33     local start = "A"
34     local v = target
35     while v ~= start do
36         table.insert(path, v)
37         v = edgeFrom[v]
38     end
39     table.insert(path, v)
40     print("shortest path: ", table.concat(path))
41 end
42 TestBfs1()

 

posted @ 2022-02-24 23:05  yanghui01  阅读(157)  评论(0编辑  收藏  举报