-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlgraph.go
132 lines (119 loc) · 3.32 KB
/
lgraph.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Love Saroha
lovesaroha1994@gmail.com (email address)
https://www.lovesaroha.com (website)
https://github.com/lovesaroha (github)
*/
package lgraph
import "fmt"
// Graph object.
type GraphObject struct {
vertices []vertexObject
directed bool
weighted bool
}
// Vertex object.
type vertexObject struct {
value interface{}
next *edgeObject
}
// Edge object.
type edgeObject struct {
vertexA interface{}
vertexB interface{}
weight float64
flow float64
next *edgeObject
}
// This function add node to given vertex.
func (vertex *vertexObject) addNode(valueA interface{}, valueB interface{}, weight float64) {
var newNode = edgeObject{vertexA: valueA, vertexB: valueB, weight: weight}
if vertex.next == nil {
// No node is added.
vertex.next = &newNode
return
}
newNode.next = vertex.next
vertex.next = &newNode
}
// This function find given vertex.
func (graph GraphObject) findVertex(value interface{}) vertexObject {
for _, vertex := range graph.vertices {
if vertex.value == value {
return vertex
}
}
return vertexObject{}
}
// This function save edge in graph.
func (graph *GraphObject) saveEdge(valueA interface{}, valueB interface{}, weight float64) {
var vertexAUpdated bool
var vertexBUpdated bool
for i, vertex := range graph.vertices {
if vertex.value == valueA {
graph.vertices[i].addNode(valueA, valueB, weight)
vertexAUpdated = true
}
if vertex.value == valueB && !graph.directed {
graph.vertices[i].addNode(valueA, valueB, weight)
vertexBUpdated = true
}
}
if !vertexAUpdated {
var vertexA = vertexObject{value: valueA}
vertexA.addNode(valueA, valueB, weight)
graph.vertices = append(graph.vertices, vertexA)
}
if !vertexBUpdated && !graph.directed {
var vertexB = vertexObject{value: valueB}
vertexB.addNode(valueA, valueB, weight)
graph.vertices = append(graph.vertices, vertexB)
}
}
// This function add edge in graph between given vertex.
func (graph *GraphObject) AddEdge(valueA interface{}, valueB interface{}) {
graph.saveEdge(valueA, valueB, 0)
}
// This function add weighted edge in graph between given vertex.
func (graph *GraphObject) AddWeightedEdge(valueA interface{}, valueB interface{}, weight float64) {
graph.weighted = true
graph.saveEdge(valueA, valueB, weight)
}
// This function show other vertex of given edge.
func (edge edgeObject) other(value interface{}) interface{} {
if edge.vertexA == value {
return edge.vertexB
}
return edge.vertexA
}
// This function return adjacent vertices.
func (graph GraphObject) PrintAdjacent(value interface{}) {
fmt.Println("Vertices adjacent to:", value)
var vertex = graph.findVertex(value)
var currentNode = vertex.next
for {
if currentNode == nil {
// No node found.
return
}
fmt.Println(currentNode.other(value))
currentNode = currentNode.next
}
}
// This function find total connected components in graph.
func (graph GraphObject) TotalConnectedComponents() int {
var totalComponents int
var visited []interface{}
var edgeTo []edgeToObject
for _, vertex := range graph.vertices {
if !isVisited(visited, vertex.value) {
// Depth first serach.
graph.depthFirstSearchRecursive(vertex.value, &visited, &edgeTo)
totalComponents++
}
}
return totalComponents
}
// This function create new graph.
func Create(directed bool) GraphObject {
return GraphObject{directed: directed}
}