1 var define = require("../define").define, 2 Collection = require("./Collection"), 3 base = require("../base"); 4 5 var padding = function(char, numSpaces) { 6 var ret = []; 7 for (var i = 0; i < numSpaces; i++) 8 ret.push(char); 9 return ret.join(""); 10 }; 11 12 module.exports = exports = define(Collection, { 13 instance : { 14 /**@lends comb.collections.Heap.prototype*/ 15 __getParentIndex : function(index) { 16 return Math.floor((index - 1) / 2); 17 }, 18 19 __getLeftChildIndex : function(index) { 20 return (index * 2) + 1; 21 }, 22 23 __getRightChildIndex : function(index) { 24 return (index * 2) + 2; 25 }, 26 27 __makeNode : function(key, value) { 28 return {key : key, value : value}; 29 }, 30 31 32 /** 33 * Base class for Heap Implementations. 34 * 35 * 36 * @constructs 37 * @augments comb.collections.Collection 38 * @memberOf comb.collections 39 * 40 * @property {Number} count the current number of elements. 41 * @property {Array} keys the keys of all items in the heap. 42 * @property {Array} values the values contained in the heap. 43 * @property {Boolean} isEmpty true if the Heap is empty. 44 */ 45 constructor : function() { 46 this.__heap = []; 47 }, 48 49 /** 50 * Insert a key value into the key 51 * @param key 52 * @param value 53 */ 54 insert : function(key, value) { 55 if (!base.isString(key)) { 56 var l = this.__heap.push(this.__makeNode(key, value)); 57 this.__upHeap(l - 1); 58 } else { 59 throw TypeError("Invalid key"); 60 } 61 }, 62 63 /** 64 * Removes the root from the heap 65 * 66 * @returns the value of the root 67 */ 68 remove : function() { 69 var ret = undefined, heap = this.__heap, l = heap.length; 70 if (l) { 71 ret = heap[0]; 72 if (l == 1) { 73 heap.length = 0; 74 } else { 75 heap[0] = heap.pop(); 76 this.__downHeap(0); 77 } 78 } 79 return ret ? ret.value : ret; 80 }, 81 82 /** 83 * Gets he value of the root node with out removing it. 84 * 85 * @returns the value of the root 86 */ 87 peek : function() { 88 var ret = undefined, heap = this.__heap, l = heap.length; 89 if (l) { 90 ret = heap[0]; 91 } 92 return ret ? ret.value : ret; 93 }, 94 95 /** 96 * Gets the key of the root node without removing it. 97 * 98 * @returns the key of the root 99 */ 100 peekKey : function() { 101 var ret = undefined, heap = this.__heap, l = heap.length; 102 if (l) { 103 ret = heap[0]; 104 } 105 return ret ? ret.key : ret; 106 }, 107 108 /** 109 * Perform the heapify operation after the an 110 * item as been added to the bottom of the heap. 111 * 112 * @param index the index in which the new item was added 113 */ 114 __upHeap : function(index) { 115 throw Error("NOT IMPLEMENTED"); 116 }, 117 118 /** 119 * Heapify the heap after the root has been removed 120 * 121 * @param index the index of the root 122 */ 123 __downHeap : function(index) { 124 throw Error("NOT IMPLEMENTED"); 125 }, 126 127 /** 128 * 129 * Determine if the heap contains a particular key. 130 * 131 * @param key key to test. 132 * 133 * @returns {Boolean} true if the key is contained in this heap. 134 */ 135 containsKey : function(key) { 136 var heap = this.__heap; 137 for (var i = heap.length - 1; i >= 0; i--) { 138 if (heap[i].key == key) { 139 return true; 140 } 141 } 142 return false; 143 }, 144 145 /** 146 * 147 * Determine if the heap contains a particular value. 148 * 149 * @param value value to test. 150 * 151 * @returns {Boolean} true if the value is contained in this heap. 152 */ 153 containsValue : function(value) { 154 var heap = this.__heap; 155 for (var i = heap.length - 1; i >= 0; i--) { 156 if (heap[i].value == value) { 157 return true; 158 } 159 } 160 return false; 161 }, 162 163 /** 164 * Empty the heap. 165 */ 166 clear : function() { 167 this.__heap.length = 0; 168 }, 169 170 __printNode : function(index, level) { 171 //console.log(level); 172 var str = [], node = this.__heap[index]; 173 if (node == null || node == undefined) { 174 str.push(padding('\t', level)); 175 str.push("~"); 176 console.log(str.join("")); 177 } else { 178 this.__printNode(this.__getRightChildIndex(index), level + 1); 179 str.push(padding('\t', level)); 180 str.push(node.key + " : " + node.value + "\n"); 181 console.log(str.join("")); 182 this.__printNode(this.__getLeftChildIndex(index), level + 1); 183 } 184 }, 185 186 /** 187 * Print the heap. 188 */ 189 print : function() { 190 this.__printNode(0, 0); 191 }, 192 193 getters : { 194 195 count : function() { 196 return this.__heap.length; 197 }, 198 199 keys : function() { 200 return this.__heap.map(function(n) { 201 return n.key; 202 }); 203 }, 204 205 values : function() { 206 return this.__heap.map(function(n) { 207 return n.value; 208 }); 209 }, 210 211 isEmpty : function() { 212 return this.__heap.length == 0; 213 } 214 } 215 216 217 } 218 });