@@ -8,90 +8,96 @@ const Queue_1 = __importDefault(require("./Queue"));
8
8
;
9
9
;
10
10
;
11
+ ;
11
12
class Graph {
12
13
constructor ( ) {
13
- this . addVertex = ( name ) => {
14
+ this . addVertex = ( name , value = null ) => {
15
+ const vertex = { key : name , value : value } ;
14
16
if ( ! this . adjacencyList [ name ] )
15
17
this . adjacencyList [ name ] = [ ] ;
18
+ if ( ! this . vertices [ name ] )
19
+ this . vertices [ name ] = vertex ;
16
20
return this . adjacencyList [ name ] ;
17
21
} ;
18
- this . addEdge = ( firstVertex , secondVertex , options = { direction : 'bi' } ) => {
22
+ this . addEdge = ( firstKey , secondKey , options = { direction : 'bi' } ) => {
19
23
// bidirectional
20
24
const { direction } = options ;
21
- if ( ! this . adjacencyList [ firstVertex ] || ! this . adjacencyList [ secondVertex ] ) {
25
+ if ( ! this . adjacencyList [ firstKey ] || ! this . adjacencyList [ secondKey ] ) {
22
26
return null ; // maybe throw error instead?
23
27
}
24
- if ( ! this . adjacencyList [ firstVertex ] . includes ( secondVertex ) ) {
25
- this . adjacencyList [ firstVertex ] . push ( secondVertex ) ;
28
+ if ( ! this . adjacencyList [ firstKey ] . find ( ( key ) => key === secondKey ) ) {
29
+ this . adjacencyList [ firstKey ] . push ( secondKey ) ;
26
30
}
27
- if ( direction === 'bi' && ! this . adjacencyList [ secondVertex ] . includes ( firstVertex ) ) {
28
- this . adjacencyList [ secondVertex ] . push ( firstVertex ) ;
31
+ if ( direction === 'bi' && ! this . adjacencyList [ secondKey ] . find ( ( key ) => key === firstKey ) ) {
32
+ this . adjacencyList [ secondKey ] . push ( firstKey ) ;
29
33
}
30
34
return this . adjacencyList ;
31
35
} ;
32
- this . removeEdge = ( firstVertex , secondVertex , options = { direction : 'bi' } ) => {
36
+ this . removeEdge = ( firstKey , secondKey , options = { direction : 'bi' } ) => {
33
37
const { direction } = options ;
34
- const firstEdge = this . adjacencyList [ firstVertex ] . findIndex ( ( edge ) => edge === secondVertex ) ;
38
+ const firstEdge = this . adjacencyList [ firstKey ] . findIndex ( ( key ) => key === secondKey ) ;
35
39
if ( firstEdge !== - 1 ) {
36
- this . adjacencyList [ firstVertex ] . splice ( firstEdge , 1 ) ;
40
+ this . adjacencyList [ firstKey ] . splice ( firstEdge , 1 ) ;
37
41
}
38
42
if ( direction === 'bi' ) {
39
- const secondEdge = this . adjacencyList [ secondVertex ] . findIndex ( ( edge ) => edge === firstVertex ) ;
43
+ const secondEdge = this . adjacencyList [ secondKey ] . findIndex ( ( key ) => key === firstKey ) ;
40
44
if ( secondEdge !== - 1 ) {
41
- this . adjacencyList [ secondVertex ] . splice ( secondEdge , 1 ) ;
45
+ this . adjacencyList [ secondKey ] . splice ( secondEdge , 1 ) ;
42
46
}
43
47
}
44
48
return this . adjacencyList ;
45
49
} ;
46
- this . removeVertex = ( vertex , options = { direction : 'bi' } ) => {
47
- if ( this . adjacencyList [ vertex ] === undefined )
50
+ this . removeVertex = ( key , options = { direction : 'bi' } ) => {
51
+ if ( this . adjacencyList [ key ] === undefined )
48
52
return null ;
49
53
const { direction } = options ;
50
54
if ( direction === 'bi' ) {
51
- for ( let edge of this . adjacencyList [ vertex ] ) {
52
- this . adjacencyList [ edge ] = this . adjacencyList [ edge ] . filter ( v => v !== vertex ) ;
55
+ for ( let edge of this . adjacencyList [ key ] ) {
56
+ this . adjacencyList [ edge ] = this . adjacencyList [ edge ] . filter ( v => v !== key ) ;
53
57
}
54
58
}
55
59
else if ( direction === 'mono' ) {
56
60
/* have to iterate over every vertex to delete any mono-directional
57
61
references to the removed vertex */
58
62
for ( let edge of Object . keys ( this . adjacencyList ) ) {
59
- this . adjacencyList [ edge ] = this . adjacencyList [ edge ] . filter ( v => v !== vertex ) ;
63
+ this . adjacencyList [ edge ] = this . adjacencyList [ edge ] . filter ( v => v !== key ) ;
60
64
}
61
65
}
62
- delete this . adjacencyList [ vertex ] ;
66
+ delete this . adjacencyList [ key ] ;
63
67
return this . adjacencyList ;
64
68
} ;
65
- this . depthFirstTraversal = ( vertex , map = v => v ) => {
69
+ this . depthFirstTraversal = ( startKey , map = v => v ) => {
66
70
// takes a starting vertex, and a map function to call on each vertex
67
71
const visited = { } ;
68
72
const results = [ ] ;
69
- const helper = ( vertex ) => {
70
- if ( ! this . adjacencyList [ vertex ] )
73
+ const helper = ( vertexKey ) => {
74
+ if ( ! this . adjacencyList [ vertexKey ] )
71
75
return ;
72
- results . push ( map ( vertex ) ) ;
73
- visited [ vertex ] = true ;
74
- for ( let neighbour of this . adjacencyList [ vertex ] ) {
76
+ results . push ( map ( this . vertices [ vertexKey ] ) ) ;
77
+ visited [ vertexKey ] = true ;
78
+ for ( let neighbour of this . adjacencyList [ vertexKey ] ) {
75
79
if ( ! visited [ neighbour ] ) {
76
80
helper ( neighbour ) ;
77
81
}
78
82
}
79
83
} ;
80
- helper ( vertex ) ;
84
+ helper ( startKey ) ;
81
85
return results ;
82
86
} ;
83
- this . iterativeDFS = ( startingVertex , map = v => v ) => {
87
+ this . iterativeDFS = ( startKey , map = v => v ) => {
88
+ if ( ! this . adjacencyList [ startKey ] )
89
+ return null ;
84
90
let stack = new Stack_1 . default ( ) ;
85
91
let results = [ ] ;
86
92
const visited = { } ;
87
- stack . push ( startingVertex ) ;
93
+ stack . push ( startKey ) ;
88
94
while ( stack . length > 0 ) {
89
95
// @ts -ignore // ignore typescript concern that stack.pop will return
90
96
// void (only happens if stack.size === 0, avoided by while loop)
91
97
let vertex = stack . pop ( ) . data ;
92
98
if ( ! visited [ vertex ] ) {
93
99
visited [ vertex ] = true ;
94
- results . push ( map ( vertex ) ) ;
100
+ results . push ( map ( this . vertices [ vertex ] ) ) ;
95
101
for ( let neighbour of this . adjacencyList [ vertex ] ) {
96
102
if ( ! visited [ neighbour ] ) {
97
103
stack . push ( neighbour ) ;
@@ -101,19 +107,20 @@ class Graph {
101
107
}
102
108
return results ;
103
109
} ;
104
- this . breathFirstTraversal = ( startingVertex , map = v => v ) => {
110
+ this . breathFirstTraversal = ( vertexKey , map = v => v ) => {
105
111
let results = [ ] ;
106
- if ( ! startingVertex )
112
+ if ( ! vertexKey )
107
113
return null ;
108
114
const queue = new Queue_1 . default ( ) ;
109
- const visited = { [ startingVertex ] : true } ;
110
- queue . enqueue ( startingVertex ) ;
115
+ const visited = { [ vertexKey ] : true } ;
116
+ queue . enqueue ( vertexKey ) ;
111
117
let dequeuedNode ;
112
118
while ( queue . length ) {
113
119
dequeuedNode = queue . dequeue ( ) ;
114
120
if ( dequeuedNode ) {
115
- results . push ( map ( dequeuedNode . data ) ) ;
116
- for ( let neighbour of this . adjacencyList [ dequeuedNode . data ] ) {
121
+ let dequeuedKey = dequeuedNode . data ;
122
+ results . push ( map ( this . vertices [ dequeuedKey ] ) ) ;
123
+ for ( let neighbour of this . adjacencyList [ dequeuedKey ] ) {
117
124
if ( ! visited [ neighbour ] ) {
118
125
visited [ neighbour ] = true ;
119
126
queue . enqueue ( neighbour ) ;
@@ -124,6 +131,7 @@ class Graph {
124
131
return results ;
125
132
} ;
126
133
this . adjacencyList = { } ;
134
+ this . vertices = { } ;
127
135
// TODO: change directional to boolean and have it be set in constructor
128
136
}
129
137
}
0 commit comments