数据结构与算法--最大堆

/**
 * 最大堆:完全二叉树,用数组保存,
 * 从数组下标 0 开始,即 父元素节点为 i, 子元素节点为 2*i+1, 2*i+2
 *                  子节点为 i(i >= 1) , 则父节点为 (i-1)/2
 *
 * count: 最大堆的有效数据长度
 */

module.exports = (function () {
  const items = new WeakMap();

  class MaxHeap {
    constructor(size) {
      this.data = [];
      this.count = 0;
    }

    swap(i1, i2) {
      [this.data[i1], this.data[i2]] = [this.data[i2], this.data[i1]];
    }

    shiftUp(k) {
      while (k >= 1) {
        let dad = Math.floor((k-1) / 2);
        if (this.data[dad] < this.data[i]) {
          this.swap(dad, i);
          k = dad;
        }
      }
    }

    shiftDown(k) {
      // k 为父节点,与子节点比较
      while ((2*k+1) < this.count) {
        let child = 2*k+1;
        if (child + 1 < this.count && this.data[child+1] > this.data[child]) {
          child += 1;
        }

        if (this.data[k] < this.data[child]) {
          this.swap(k, child);
          k = child;
        } else {
          break;
        }
      }
    }

    /**
     * 往最大堆中插入一条数据
     * @param item
     */
    insert(item) {
      this.data[this.count++] = item;
      this.shiftUp(this.data.length - 1);
    }

    /**
     * 删除最大堆的最大值,并保持最大堆的性质
     */
    extractMax() {
      // 交换第一个和最后一个数
      const res = this.data[this.count - 1];
      this.swap(this.count, 0);
      this.count--;
      this.shiftDown(0);
      return res;
    }

    size() {
      return this.size;
    }
  }
})();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值