From 1e73051e6cda4843a54ac3adbcd02ee683ae3aac Mon Sep 17 00:00:00 2001 From: Felipe Ribeiro Date: Sun, 3 Aug 2014 22:34:20 +0200 Subject: [PATCH] Refactoring in PQ and Dijkstra --- algorithms/graph/dijkstra.js | 20 +++++++++---------- data_structures/priority_queue.js | 27 +++++++++++++------------- test/data_structures/priority_queue.js | 11 ++++++++--- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/algorithms/graph/dijkstra.js b/algorithms/graph/dijkstra.js index 1c39455..da08795 100644 --- a/algorithms/graph/dijkstra.js +++ b/algorithms/graph/dijkstra.js @@ -24,19 +24,17 @@ function dijkstra(graph, s) { }); var currNode; + var relax = function (v) { + var newDistance = distance[currNode] + graph.edge(currNode, v); + if (newDistance < distance[v]) { + distance[v] = newDistance; + previous[v] = currNode; + q.changePriority(v, distance[v]); + } + }; while (!q.isEmpty()) { currNode = q.extract(); - var neighbors = graph.neighbors(currNode); - for (var i = 0; i < neighbors.length; i++) { - var v = neighbors[i]; - // relaxation - var newDistance = distance[currNode] + graph.edge(currNode, v); - if (newDistance < distance[v]) { - distance[v] = newDistance; - previous[v] = currNode; - q.changePriority(v, distance[v]); - } - } + graph.neighbors(currNode).forEach(relax); } return { distance: distance, diff --git a/data_structures/priority_queue.js b/data_structures/priority_queue.js index 18083e7..4e6f32b 100644 --- a/data_structures/priority_queue.js +++ b/data_structures/priority_queue.js @@ -8,14 +8,15 @@ var MinHeap = require('./heap').MinHeap; * and not on the element itself */ function PriorityQueue(initialItems) { + + var self = this; MinHeap.call(this, function (a, b) { - return a.priority < b.priority ? -1 : 1; + return self._priority[a] < self._priority[b] ? -1 : 1; }); - this._items = {}; + this._priority = {}; initialItems = initialItems || {}; - var self = this; Object.keys(initialItems).forEach(function (item) { self.insert(item, initialItems[item]); }); @@ -24,26 +25,26 @@ function PriorityQueue(initialItems) { PriorityQueue.prototype = new MinHeap(); PriorityQueue.prototype.insert = function (item, priority) { - var o = { - item: item, - priority: priority - }; - - this._items[item] = o; - MinHeap.prototype.insert.call(this, o); + if (this._priority[item] !== undefined) { + return this.changePriority(item, priority); + } + this._priority[item] = priority; + MinHeap.prototype.insert.call(this, item); }; PriorityQueue.prototype.extract = function (withPriority) { var min = MinHeap.prototype.extract.call(this); - return withPriority ? min : min && min.item; + return withPriority ? + min && {item: min, priority: this._priority[min]} : + min; }; PriorityQueue.prototype.priority = function (item) { - return this._items[item].priority; + return this._priority[item]; }; PriorityQueue.prototype.changePriority = function (item, priority) { - this._items[item].priority = priority; + this._priority[item] = priority; this.heapify(); }; diff --git a/test/data_structures/priority_queue.js b/test/data_structures/priority_queue.js index e1ff46f..4fa8b09 100644 --- a/test/data_structures/priority_queue.js +++ b/test/data_structures/priority_queue.js @@ -65,11 +65,16 @@ describe('Min Priority Queue', function () { assert(!q.isEmpty()); q.changePriority('b', 0); + q.changePriority('a', 1); + q.changePriority('c', 50); + q.changePriority('d', 1000); + q.changePriority('e', 2); + assert.equal(q.extract(), 'b'); - assert.equal(q.extract(), 'd'); - assert.equal(q.extract(), 'c'); - assert.equal(q.extract(), 'e'); assert.equal(q.extract(), 'a'); + assert.equal(q.extract(), 'e'); + assert.equal(q.extract(), 'c'); + assert.equal(q.extract(), 'd'); }); });