1
+
2
+ /**
3
+ * A node for priorioty linked list / stack and such
4
+ */
5
+ class PriorityNode {
6
+ key :number ;
7
+ priority :number ;
8
+
9
+ constructor ( key : number , priority : number ) {
10
+ this . key = key ;
11
+ this . priority = priority ;
12
+ }
13
+ }
14
+
15
+ /**
16
+ * A priority queue with highest priority always on top
17
+ * This queue is sorted by priority for each enqueue
18
+ */
19
+ class PriorityQueue {
20
+
21
+ nodes :PriorityNode [ ] = [ ] ;
22
+
23
+ /**
24
+ * Enqueue a new node
25
+ * @param {[type] } priority
26
+ * @param {[type] } key
27
+ */
28
+ enqueue ( priority :number , key :number ) {
29
+ this . nodes . push ( new PriorityNode ( key , priority ) ) ;
30
+ this . nodes . sort (
31
+ function ( a , b ) {
32
+ return a . priority - b . priority ;
33
+ }
34
+ )
35
+ }
36
+
37
+ /**
38
+ * Dequeue the highest priority key
39
+ */
40
+ dequeue ( ) :number {
41
+ return this . nodes . shift ( ) . key ;
42
+ }
43
+
44
+ /**
45
+ * Checks if empty
46
+ */
47
+ empty ( ) :boolean {
48
+ return ! this . nodes . length ;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Computes the shortest path between two node
54
+ */
55
+ class Dijkstra {
56
+
57
+ infinity = 1 / 0 ;
58
+ vertices = { } ;
59
+
60
+ /**
61
+ * Add a new vertex and related edges
62
+ * @param {[type] } name [description]
63
+ * @param {[type] } edges [description]
64
+ */
65
+ addVertex ( name :string , edges :any ) {
66
+ this . vertices [ name ] = edges ;
67
+ }
68
+
69
+ /**
70
+ * Computes the shortest path from start to finish
71
+ * @param {[type] } start [description]
72
+ * @param {[type] } finish [description]
73
+ */
74
+ shortestPath ( start :string , finish :string ) {
75
+
76
+ let nodes = new PriorityQueue ( ) ,
77
+ distances = { } ,
78
+ previous = { } ,
79
+ path = [ ] ,
80
+ smallest ,
81
+ vertex ,
82
+ neighbor ,
83
+ alt ;
84
+
85
+ //Init the distances and queues variables
86
+ for ( vertex in this . vertices ) {
87
+ if ( vertex === start ) {
88
+ distances [ vertex ] = 0 ;
89
+ nodes . enqueue ( 0 , vertex ) ;
90
+ } else {
91
+ distances [ vertex ] = this . infinity ;
92
+ nodes . enqueue ( this . infinity , vertex ) ;
93
+ }
94
+
95
+ previous [ vertex ] = null ;
96
+ }
97
+
98
+ //continue as long as the queue haven't been emptied.
99
+ while ( ! nodes . empty ( ) ) {
100
+
101
+
102
+ smallest = nodes . dequeue ( ) ;
103
+
104
+ //we are the last node
105
+ if ( smallest === finish ) {
106
+
107
+ //Compute the path
108
+ while ( previous [ smallest ] ) {
109
+ path . push ( smallest ) ;
110
+ smallest = previous [ smallest ] ;
111
+ }
112
+ break ;
113
+ }
114
+
115
+ //No distance known. Skip.
116
+ if ( ! smallest || distances [ smallest ] === this . infinity ) {
117
+ continue ;
118
+ }
119
+
120
+ //Compute the distance for each neighbor
121
+ for ( neighbor in this . vertices [ smallest ] ) {
122
+ alt = distances [ smallest ] + this . vertices [ smallest ] [ neighbor ] ;
123
+
124
+ if ( alt < distances [ neighbor ] ) {
125
+ distances [ neighbor ] = alt ;
126
+ previous [ neighbor ] = smallest ;
127
+ nodes . enqueue ( alt , neighbor ) ;
128
+ }
129
+ }
130
+ }
131
+ //the starting point isn't in the solution &
132
+ //the solution is from end to start.
133
+ return path . concat ( start ) . reverse ( ) ;
134
+ }
135
+ }
136
+
137
+ let graph :Dijkstra = new Dijkstra ( ) ;
138
+ graph . addVertex ( 'A' , { B : 7 , C : 8 } ) ;
139
+ graph . addVertex ( 'C' , { A : 8 } ) ;
140
+ graph . addVertex ( 'B' , { A : 7 , F : 8 } ) ;
141
+ graph . addVertex ( 'F' , { B : 8 } ) ;
142
+
143
+ console . log ( graph . shortestPath ( 'A' , 'F' ) ) ;
0 commit comments