数据结构-堆-代码讲解

175 阅读2分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

堆-代码讲解

介绍

的介绍,在上篇已经讲过了 数据结构-堆,想先了解概念的小伙伴,可以先了解下什么是 。这样也便于下边对 代码的一个理解。

问题

数据结构-堆 这篇文章中,暴露出来的问题,就是一个 非 堆 的数组,如何用 js代码 的形式转化成一个 数组。

这是上篇文章用到的 非 堆 图,这里引用下来。

image.png

可以看到 这个 完全二叉树 数组的值为 [7,15,1,20,2,9,3,6]

那如何得到我们想要的 的图的结果呢,结果图:

image.png

这个 的结果为 [20,15,3,7,9,2,1,6]

[7,15,1,20,2,9,3,6] ---> [20,15,3,7,9,2,1,6] 的转化,我们下面用代码的形式讲解下。

注:这里重点补充一下,代码结果可能跟图上的不一样

  • 因为打乱后的数据是随便写的,也就是随机的。如果想恢复成一模一样,就不是随机,就要添加相关的约束规则,来产生数据。

  • 图上最终的结果 只是起到参考类比的作用,但最终的结果的结构都是 数据结构 堆

解决

主要是通过循环遍历的思想来解决。配合公式

  • 当前节点:i

  • 父节点: Math.floor((i-1)/2)

  • 两个子节点分别为:

    • 左孩子:2i + 1

    • 右孩子: 2i+2

  • 再通过 循环重新赋值,依次向上查找,直至退出循环

  • 代码如下

        const dataArray = []
    
        // 初始化数据
        const initDataArray = (arr) => {
          arr.forEach((item) => {
            insert(item)
          })
        }
    
        // 获取 当前元素 的 父元素 下标
        const getFatherIndex = (index) => {
          return Math.floor((index - 1) / 2)
        }
    
        // 交换值
        const isExchange = (currentIndex, currentFatherIndex) => {
          const temp = dataArray[currentFatherIndex]
          dataArray[currentFatherIndex] = dataArray[currentIndex]
          dataArray[currentIndex] = temp
        }
    
        // 插入新元素
        const insert = (value) => {
          dataArray.push(value)
    
          // 获取 当前元素 的 下标
          let currentIndex = dataArray.length - 1
    
          // 获取 当前元素 的 父元素 下标
          let currentFatherIndex = getFatherIndex(currentIndex)
    
          // 判断 元素的父元素的下标是否存在
          while (currentFatherIndex >= 0) {
            // 如果 当前元素 的值 大于 当前元素的父元素 的值,进行交换操作
            if (dataArray[currentIndex] > dataArray[currentFatherIndex]) {
              isExchange(currentIndex, currentFatherIndex)
            }
    
            // 更新 当前元素下标 和 父元素下标
            currentIndex = currentFatherIndex
            currentFatherIndex = getFatherIndex(currentIndex)
          }
        }
    
        // 输出
        const print = () => {
          console.log(dataArray)
        }
    
        // initDataArray([20, 15, 3, 7, 9, 2, 1, 6])
        initDataArray([7, 15, 1, 20, 2, 9, 3, 6])
        print()