|
1 | 1 | var jsgraphs = jsgraphs || {}; |
2 | 2 |
|
3 | 3 | (function(jss){ |
| 4 | + |
| 5 | + jss.less = function(a1, a2, compare) { |
| 6 | + return compare(a1, a2) < 0; |
| 7 | + }; |
| 8 | + |
| 9 | + jss.exchange = function(a, i, j) { |
| 10 | + var temp = a[i]; |
| 11 | + a[i] = a[j]; |
| 12 | + a[j] = temp; |
| 13 | + }; |
| 14 | + |
4 | 15 | var StackNode = function (value) { |
5 | 16 | this.value = value; |
6 | 17 | this.next = null; |
@@ -133,6 +144,102 @@ var jsgraphs = jsgraphs || {}; |
133 | 144 |
|
134 | 145 | jss.Queue = Queue; |
135 | 146 |
|
| 147 | + var MinPQ = function(compare) { |
| 148 | + this.s = []; |
| 149 | + this.N = 0; |
| 150 | + if(!compare) { |
| 151 | + compare = function(a1, a2) { |
| 152 | + return a1 - a2; |
| 153 | + }; |
| 154 | + } |
| 155 | + this.compare = compare; |
| 156 | + }; |
| 157 | + |
| 158 | + MinPQ.prototype.enqueue = function(item) { |
| 159 | + while(this.s.lengh <= this.N+1) { |
| 160 | + this.s.push(0); |
| 161 | + } |
| 162 | + this.s[++this.N] = item; |
| 163 | + this.swim(this.N); |
| 164 | + }; |
| 165 | + |
| 166 | + MinPQ.prototype.swim = function(k) { |
| 167 | + while (k > 1){ |
| 168 | + var parent = Math.floor(k / 2); |
| 169 | + if(jss.less(this.s[k], this.s[parent], this.compare)){ |
| 170 | + jss.exchange(this.s, k, parent); |
| 171 | + k = parent; |
| 172 | + } else { |
| 173 | + break; |
| 174 | + } |
| 175 | + } |
| 176 | + }; |
| 177 | + |
| 178 | + MinPQ.prototype.delMin = function() { |
| 179 | + if(this.N == 0) { |
| 180 | + return undefined; |
| 181 | + } |
| 182 | + |
| 183 | + var item = this.s[1]; |
| 184 | + jss.exchange(this.s, 1, this.N--); |
| 185 | + this.sink(1); |
| 186 | + return item; |
| 187 | + }; |
| 188 | + |
| 189 | + MinPQ.prototype.sink = function(k) { |
| 190 | + while(k * 2 <= this.N) { |
| 191 | + var child = 2 * k; |
| 192 | + if(child < this.N && jss.less(this.s[child+1], this.s[child], this.compare)){ |
| 193 | + child++; |
| 194 | + } |
| 195 | + if(jss.less(this.s[child], this.s[k], this.compare)){ |
| 196 | + jss.exchange(this.s, child, k); |
| 197 | + k = child; |
| 198 | + } else { |
| 199 | + break; |
| 200 | + } |
| 201 | + } |
| 202 | + }; |
| 203 | + |
| 204 | + MinPQ.prototype.size = function(){ |
| 205 | + return this.N; |
| 206 | + }; |
| 207 | + |
| 208 | + MinPQ.prototype.isEmpty = function() { |
| 209 | + return this.N == 0; |
| 210 | + }; |
| 211 | + |
| 212 | + jss.MinPQ = MinPQ; |
| 213 | + |
| 214 | + var QuickUnion = function(V) { |
| 215 | + this.id = []; |
| 216 | + for (var v = 0; v < V; ++v) { |
| 217 | + this.id.push(v); |
| 218 | + } |
| 219 | + }; |
| 220 | + |
| 221 | + QuickUnion.prototype.union = function(v, w) { |
| 222 | + var q = this.root(v); |
| 223 | + var p = this.root(w); |
| 224 | + |
| 225 | + if(p != q) { |
| 226 | + this.id[p] = q; |
| 227 | + } |
| 228 | + }; |
| 229 | + |
| 230 | + QuickUnion.prototype.root = function(q) { |
| 231 | + while(this.id[q] != q) { |
| 232 | + q = this.id[q]; |
| 233 | + } |
| 234 | + return q; |
| 235 | + }; |
| 236 | + |
| 237 | + QuickUnion.prototype.connected = function(v, w) { |
| 238 | + return this.root(v) == this.root(w); |
| 239 | + }; |
| 240 | + |
| 241 | + jss.QuickUnion = QuickUnion; |
| 242 | + |
136 | 243 | var Graph = function (V) { |
137 | 244 | this.V = V; |
138 | 245 | this.adjList = []; |
@@ -433,6 +540,41 @@ var jsgraphs = jsgraphs || {}; |
433 | 540 | }; |
434 | 541 |
|
435 | 542 | jss.StronglyConnectedComponents = StronglyConnectedComponents; |
| 543 | + |
| 544 | + var KruskalMST = function(G) { |
| 545 | + var V = G.V; |
| 546 | + var pq = new jss.MinPQ(function(e1, e2){ |
| 547 | + return e1.weight - e2.weight; |
| 548 | + }); |
| 549 | + for(var v = 0; v < G.V; ++v){ |
| 550 | + var adj_v = G.adj(v); |
| 551 | + for (var i = 0; i < adj_v.length; ++i) { |
| 552 | + var e = adj_v[i]; |
| 553 | + if(e.either() != v) { |
| 554 | + continue; |
| 555 | + } |
| 556 | + pq.enqueue(e); |
| 557 | + } |
| 558 | + } |
| 559 | + |
| 560 | + this.mst = []; |
| 561 | + |
| 562 | + var uf = new jss.QuickUnion(V); |
| 563 | + while (!pq.isEmpty() && this.mst.length < V-1) { |
| 564 | + var e = pq.delMin(); |
| 565 | + var v = e.either(); |
| 566 | + var w = e.other(v); |
| 567 | + |
| 568 | + if(!uf.connected(v, w)){ |
| 569 | + uf.union(v, w); |
| 570 | + this.mst.push(e); |
| 571 | + } |
| 572 | + } |
| 573 | + }; |
| 574 | + |
| 575 | + |
| 576 | + |
| 577 | + jss.KruskalMST = KruskalMST; |
436 | 578 |
|
437 | 579 | })(jsgraphs); |
438 | 580 |
|
|
0 commit comments