YBFACC / blog

仅记录个人学习使用
3 stars 0 forks source link

二叉堆 #34

Open YBFACC opened 4 years ago

YBFACC commented 4 years ago

二叉堆

可以实现大顶堆或者小顶堆。

可以便利的解决一类 topK 问题。

215. 数组中的第K个最大元素

可视化工具

以小顶堆为例:

插入

11

12

弹出

444

555

666

777

代码

function swap(arr, i, j) {
  ;[arr[i], arr[j]] = [arr[j], arr[i]]
}

class MinHeap {
  constructor(arr = []) {
    this.container = []
    if (Array.isArray(arr)) {
      arr.forEach(this.insert.bind(this))
    }
  }

  insert(data) {
    const { container } = this

    container.push(data)
    let index = container.length - 1
    while (index) {
      let parent = Math.floor((index - 1) / 2)
      if (container[index] >= container[parent]) {
        break
      }
      swap(container, index, parent)
      index = parent
    }
  }

  extract() {
    const { container } = this
    if (!container.length) {
      return null
    }

    swap(container, 0, container.length - 1)
    const res = container.pop()
    const length = container.length
    let index = 0,
      exchange = index * 2 + 1

    while (exchange < length) {
      let right = index * 2 + 2
      if (right < length && container[right] < container[exchange]) {
        exchange = right
      }
      if (container[exchange] >= container[index]) {
        break
      }
      swap(container, exchange, index)
      index = exchange
      exchange = index * 2 + 1
    }

    return res
  }

  top() {
    if (this.container.length) return this.container[0]
    return null
  }
}

function getMin(arr) {
  const heap = new MinHeap(arr.slice())
  for (let i = 0; i < arr.length; ++i) {
    console.log(heap.extract())
  }
}

getMin([4, 5, 8, 2, 1, 10, 11, 5, 7, 9, 5, 7])