在堆中,构建堆、插入、删除过程都需要大量的交换操作。在之前的实现中,进行交换操作是直接交换数组中两个元素。而索引堆交换的是这两个元素的索引,而不是直接交换元素。
主要有两个好处:
function IndexMaxHeap(capacity) {// 最大索引堆中的数据this.data = new Array(capacity + 1);// 最大索引堆中的索引,indexes[x] = i 表示索引 i 在 x 的位置this.indexes = [];// 最大索引堆中的反向索引,reverse[i] = x 表示索引 i 在 x 的位置this.reverse = [];this.count = 0;this.capacity = capacity;// 将反向索引默认填充为 0for (let i = 0; i <= capacity; i++) {this.reverse[i] = 0;};}// 返回索引堆中的元素个数IndexMaxHeap.prototype.size = function() {return this.count;}// 表示索引堆中是否为空IndexMaxHeap.prototype.isEmpty = function() {return this.count === 0;};// 向最大索引堆中插入一个新的元素,新元素的索引为 index,元素为 valueIndexMaxHeap.prototype.insert = function(index, value) {index += 1;this.data[index] = value;this.indexes[this.count + 1] = index;this.revers[index] = this.count + 1;this.count++;this.heapifyUp(this.count);};// 从最大索引堆中取出堆顶元素,即索引堆中所存储的最大数据IndexMaxHeap.prototype.extractMax = function() {const maxValue = this.data[this.indexs[1]];this.swap(1, this.count);this.reverse[this.indexes[1]] = 1;this.reverse[this.indexes[this.count]] = 0;this.count--;this.heapifyDown(1);return maxValue;};// 从最大索引堆中取出堆顶元素的索引IndexMaxHeap.prototype.extractMaxIndex = function() {const maxIndex = this.indexes[1] - 1;this.swap(1, this.count);this.reverse[this.indexes[1]] = 1;this.reverse[this.indexes[this.count]] = 0;this.count--;this.heapifyDown(1);return maxIndex};IndexMaxHeap.prototype.contain = function (index) {return this.reverse[index + 1] !== 0;}IndexMaxHeap.prototype.heapifyUp = function(k) {};IndexMaxHeap.prototype.heapifyDown = function(k) {};// 交换索引堆中的索引 i 和 j// 由于有了反向索引 reverse 数组// indexes 数组发生改变以后,相应的就需要维护 reverse 数组IndexMaxHeap.prototype.swap = function (i, j) {[this.data[i], this.data[j]] = [this.data[j], this.data.[i]];this.reverse[this.indexes[i]] = i;this.reverse[this.indexes[j]] = j;};IndexMaxHeap.prototype.getItem = function (index) {return this.data[index + 1];}// 将最大索引堆中索引为 i 的元素修改为 newValueIndexMaxHeap.prototype.change = function(index, newValue) {index += 1;this.data[index] = newValue;const reverseIndex = reverse[index];this.heapifyUp(reverseIndex);this.heapifyDown(reverseIndex);};
参考资料