PriorityQueue.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * PriorityQueue
  3. * Elements in this queue are sorted according to their value
  4. *
  5. * @author Lukasz Krawczyk <contact@lukaszkrawczyk.eu>
  6. * @copyright MIT
  7. */
  8. /**
  9. * PriorityQueue class construcotr
  10. * @constructor
  11. *
  12. * @example
  13. * queue: [1,2,3,4]
  14. * priorities: [4,1,2,3]
  15. * > result = [1,4,2,3]
  16. *
  17. * @param {Array} elements
  18. * @param {Array} priorities
  19. * @param {string} sorting - asc / desc
  20. * @returns {PriorityQueue}
  21. */
  22. function PriorityQueue(elements, priorities, sorting) {
  23. /** @type {Array} */
  24. this._queue = [];
  25. /** @type {Array} */
  26. this._priorities = [];
  27. /** @type {string} */
  28. this._sorting = 'desc';
  29. this._init(elements, priorities, sorting);
  30. };
  31. /**
  32. * Insert element
  33. *
  34. * @param {Object} ele
  35. * @param {Object} priority
  36. * @returns {undefined}
  37. * @access public
  38. */
  39. PriorityQueue.prototype.insert = function(ele, priority) {
  40. var indexToInsert = this._queue.length;
  41. var index = indexToInsert;
  42. while (index--) {
  43. var priority2 = this._priorities[index];
  44. if (this._sorting === 'desc') {
  45. if (priority > priority2) {
  46. indexToInsert = index;
  47. }
  48. } else {
  49. if (priority < priority2) {
  50. indexToInsert = index;
  51. }
  52. }
  53. }
  54. this._insertAt(ele, priority, indexToInsert);
  55. };
  56. /**
  57. * Remove element
  58. *
  59. * @param {Object} ele
  60. * @returns {undefined}
  61. * @access public
  62. */
  63. PriorityQueue.prototype.remove = function(ele) {
  64. var index = this._queue.length;
  65. while (index--) {
  66. var ele2 = this._queue[index];
  67. if (ele === ele2) {
  68. this._queue.splice(index, 1);
  69. this._priorities.splice(index, 1);
  70. break;
  71. }
  72. }
  73. };
  74. /**
  75. * For each loop wrapper
  76. *
  77. * @param {function} func
  78. * @returs {undefined}
  79. * @access public
  80. */
  81. PriorityQueue.prototype.forEach = function(func) {
  82. this._queue.forEach(func);
  83. };
  84. /**
  85. * @returns {Array}
  86. * @access public
  87. */
  88. PriorityQueue.prototype.getElements = function() {
  89. return this._queue;
  90. };
  91. /**
  92. * @param {number} index
  93. * @returns {Object}
  94. * @access public
  95. */
  96. PriorityQueue.prototype.getElementPriority = function(index) {
  97. return this._priorities[index];
  98. };
  99. /**
  100. * @returns {Array}
  101. * @access public
  102. */
  103. PriorityQueue.prototype.getPriorities = function() {
  104. return this._priorities;
  105. };
  106. /**
  107. * @returns {Array}
  108. * @access public
  109. */
  110. PriorityQueue.prototype.getElementsWithPriorities = function() {
  111. var result = [];
  112. for (var i = 0, l = this._queue.length; i < l; i++) {
  113. result.push([this._queue[i], this._priorities[i]]);
  114. }
  115. return result;
  116. };
  117. /**
  118. * Set object properties
  119. *
  120. * @param {Array} elements
  121. * @param {Array} priorities
  122. * @returns {undefined}
  123. * @access protected
  124. */
  125. PriorityQueue.prototype._init = function(elements, priorities, sorting) {
  126. if (elements && priorities) {
  127. this._queue = [];
  128. this._priorities = [];
  129. if (elements.length !== priorities.length) {
  130. throw new Error('Arrays must have the same length');
  131. }
  132. for (var i = 0; i < elements.length; i++) {
  133. this.insert(elements[i], priorities[i]);
  134. }
  135. }
  136. if (sorting) {
  137. this._sorting = sorting;
  138. }
  139. };
  140. /**
  141. * Insert element at given position
  142. *
  143. * @param {Object} ele
  144. * @param {number} index
  145. * @returns {undefined}
  146. * @access protected
  147. */
  148. PriorityQueue.prototype._insertAt = function(ele, priority, index) {
  149. if (this._queue.length === index) {
  150. this._queue.push(ele);
  151. this._priorities.push(priority);
  152. } else {
  153. this._queue.splice(index, 0, ele);
  154. this._priorities.splice(index, 0, priority);
  155. }
  156. };
  157. if (typeof module !== 'undefined' && module.exports) {
  158. module.exports = PriorityQueue;
  159. }