无向图的连通分量计算

# 从某个顶点出发,访问到其能访问的所有其他顶点,这些顶点是属于一个连通分量的。

# 以此类推,将图的每个顶点都作为出发点一次。

 1 local ConnectedComponent = {}
 2 ConnectedComponent.__index = ConnectedComponent
 3 
 4 function ConnectedComponent.new()
 5     local obj = {}
 6     setmetatable(obj, ConnectedComponent)
 7     obj:ctor()
 8     return obj
 9 end
10 
11 function ConnectedComponent:ctor()
12     self.graph = nil
13     self.vertexComponent = nil ---顶点所属的连通分量
14     self.componentId = 0
15 end
16 
17 function ConnectedComponent:Calc(graph)
18     self.graph = graph
19     self.vertexComponent = {}
20     self.componentId = 0
21     local visited = {}
22 
23     local function dfsVisitAllReachable(v)
24         visited[v] = true
25         self.vertexComponent[v] = self.componentId
26 
27         local adjList = graph:GetAdjacent(v)
28         for i=1,#adjList do
29             local adjV = adjList[i]
30             if not visited[adjV] then
31                 dfsVisitAllReachable(adjV)
32             end
33         end
34     end
35 
36     for i=1,graph:GetVertexCount() do
37         local v = graph:GetVertex(i)
38         if not visited[v] then
39             dfsVisitAllReachable(v) --这个顶点能访问到的所有顶点属于同一个连通分量
40             self.componentId = self.componentId + 1
41         end
42     end
43 end
44 
45 function ConnectedComponent:IsConnected(v1, v2)
46     return self.vertexComponent[v1] == self.vertexComponent[v2] --是否属于同一个连通分量
47 end
48 
49 ---连通分量数量
50 function ConnectedComponent:GetCount()
51     return self.componentId
52 end
53 
54 ---顶点所属连通分量id
55 function ConnectedComponent:GetComponentId(v)
56     return self.vertexComponent[v]
57 end
58 
59 function ConnectedComponent:Dump()
60     local ccVertexListTb = {} ---连通分量的顶点队列
61 
62     for i=1,self.graph:GetVertexCount() do
63         local v = self.graph:GetVertex(i)
64         local cid = self:GetComponentId(v)
65         local queue = ccVertexListTb[cid]
66         if nil == queue then
67             queue = {}
68             ccVertexListTb[cid] = queue
69         end
70         table.insert(queue, v)
71     end
72 
73     for k_v, v_list in pairs(ccVertexListTb) do
74         print(table.concat(v_list, ","))
75     end
76 end

 

使用下面的图进行测试:

 

 

 1 function CreateGraph()
 2     local g = Graph.new()
 3 
 4     g:AddVertex("0")
 5     g:AddVertex("1")
 6     g:AddVertex("2")
 7     g:AddEdge("0", "1")
 8     g:AddEdge("0", "2")
 9 
10     g:AddVertex("3")
11 
12     g:AddVertex("4")
13     g:AddVertex("5")
14     g:AddVertex("6")
15     g:AddVertex("7")
16     g:AddEdge("4", "5")
17     g:AddEdge("4", "6")
18     g:AddEdge("5", "7")
19 
20     g:AddVertex("8")
21     g:AddVertex("9")
22     g:AddEdge("8", "9")
23 
24     tostring(g)
25     return g
26 end
27 
28 function Test1()
29     local g = CreateGraph()
30     local cc = ConnectedComponent.new()
31     cc:Calc(g)
32     cc:Dump()
33 end
34 Test1()

 

【参考】

图论算法——无向图的连通分量_日积月累,天道酬勤-CSDN博客_无向图的连通分量

 

posted @ 2022-03-13 21:10  yanghui01  阅读(297)  评论(0编辑  收藏  举报