UNPKG

jstructures

Version:

The project is JavaScript Data Structures incudes Vector, List, Tree, Graph, Heap...etc

146 lines (131 loc) 2.98 kB
/** * Heap 堆 * @class * @return {Heap} Instance */ function Heap(elems = [], length = 0) { const data = length ? elems.slice(0, length) : []; // 堆的实际物理存储,一个边长数组 const that = {}; Object.defineProperty(that, "size", { /** * 获取堆的大小 * @time O(1) * @space O(0) * @memberof Heap * @name size * @instance * * @return {number} */ get: function size() { return data.length; } }); const swap = (i, j) => { const t = data[i]; data[i] = data[j]; data[j] = t; }; /** * 得到父子三者(最多三个) 中的最大值 */ const properParent = (n, i) => { const lIndex = 1 + (i << 1); const rIndex = (1 + i) << 1; if (rIndex < n && data[rIndex] > data[lIndex] && data[rIndex] > data[i]) return rIndex; if (lIndex < n && data[lIndex] > data[i]) return lIndex; return i; }; /** * 元素上滤操作 * @time O(LogN) * @space O(1) * @memberof Heap * @instance * * @param {Number} i 上滤的元素索引 * @return {Number} 上滤的终止位置 */ const percolateUp = i => { while (0 < i) { const j = (i - 1) >> 1; // 计算父节点索引值 if (data[i] < data[j]) break; // 一旦当前父子不再逆序上滤完成 swap(i, j); // 否则交换父子 i = j; } return i; // 返回上滤最终抵达的位置 }; /** * 元素下滤操作 * @time O(LogN) * @space O(1) * @memberof Heap * @instance * * @param {Number} i 下滤的元素索引 * @return {Number} 下滤的终止位置 */ const percolateDown = i => { let j; while (i !== (j = properParent(data.length, i))) { swap(i, j); i = j; } return i; // 返回下滤滴答的位置 }; /** * e 元素插入 * @time O(LogN) * @space O(1) * @memberof Heap * @instance * * @param {Anyone} e * @return {void} */ that.insert = function insert(e) { // 首先将元素插入末尾,之后执行上滤 data.push(e); percolateUp(that.size - 1); }; /** * 返回堆的最大元素 * @time O(1) * @space O(1) * @memberof Heap * @instance * * @return {Anyone} */ that.getMax = function getMax() { return data[0]; }; /** * 删除堆的最大元素 * @time O(LogN) * @space O(1) * @memberof Heap * @instance * * @param {Anyone} e * @return {void} */ that.delMax = function delMax() { const maxElem = data[0]; // 删除第一个元素代之以最后一个元素 data[0] = data[data.length - 1]; data.length -= 1; percolateDown(0); return maxElem; }; // 批量建堆 const heapify = n => { for (let i = (n - 2) >> 1; 0 <= i && i < n; i -= 1) { // 自底而上,依次下滤内部各节点 percolateDown(i); } }; if (0 < length) heapify(length); return that; } module.exports = Heap;