堆排序之索引堆

250 阅读2分钟

我们先来看下面这两张图: 这两张图是形成最大堆的前后两个数组。 image.png image.png 我们会发现,当我们任意的数组形成最大堆之后,索引会发生变化。如果我第一张图的15,优先级最大,要先执行。我们该如何解决?

思考:
  • 解决的方式可能是要加入ID
  • 但是加入ID之后,我们会发现我们还要再次的遍历查找
  • 如何解决这样的问题?
  • 这就是索引堆的作用 接下来我们以最大索引堆为例,看下面两图:
  • 第一张图是没有形成最大堆的索引
  • 第二张图是形成了最大堆的索引图 image.png image.png 我们来看第二张图:
  • index那一行的10所对应的是,真正数组索引10的位置,也就是值为62
  • 那index那一行9所对应的是,真正数组索引9的位置,也就是41
  • 剩下的以此类推
思考:

如何实现一个索引堆?

  • 我们不仅需要一个随机的数组,还需要一个对应索引的数组
  • 我们的shift up是往最大堆中添加一个元素,之后进行最大堆的排序操作。
  • 我们现在不需要添加,而是直接使用shift up进行排序
  • 排序谁?排序的就是我们的index
  • 如何对应?arr[indexArr[parseInt(k/2)]]比arr[indexArr[k]]小,就将对应的索引交换。
  • 思路顺了,我们接下来具体实现。
// 索引堆
let arrIndex = ["", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let arrNumber = ["", 15, 17, 19, 13, 22, 16, 28, 30, 42, 62]
function swap(arr, l, r) {
    [arr[l], arr[r]] = [arr[r], arr[l]]
}
function shiftUp(arrNumber, arrIndex, k) {
    while (k > 1 && arrNumber[arrIndex[parseInt(k / 2)]] < arrNumber[arrIndex[k]]) {
        swap(arrIndex, parseInt(k / 2), k)
        k /= 2
    }
    return arrIndex
}
console.log(shiftUp(arrNumber, arrIndex, arrNumber.length-1)) // [ '', 1, 10, 3, 4, 2,  6, 7,  8, 9, 5]

上面最后打印出的索引就是最大堆元素位置,通过索引进行的排序。

作用:
  • 知道索引,去最大索引堆中获取索引值。
  • 拿着索引的值,获取对应的值。

总结

单独来看索引堆,解决的问题并不是那么理想,如果是单纯为了寻找一个值,不如改成hash表结构,使用key直接就能找到value,去改变他的优先级。

但是索引堆有其他的作用,这里只是简单的理解什么是索引堆,之后再进行更深的使用。

如有错误,还望指正,谢谢大家!!!