103 阅读2分钟

堆是一个完全二叉树,堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。第一点,堆必须是一个完全二叉树。还记得我们之前讲的完全二叉树的定义吗?完全二叉树要求,除了最后一层,其他层的节点个数都是满的,最后一层的节点都靠左排列。第二点,堆中的每个节点的值必须大于等于(或者小于等于)其子树中每个节点的值。实际上,我们还可以换一种说法,堆中每个节点的值都大于等于(或者小于等于)其左右子节点的值。这两种表述是等价的。

4d349f57947df6590a2dd1364c3b0b1e.jpg.webp `

class HeapSort {
  constructor(originArray) {
    this.originArray = originArray;
    console.log(this.originArray)
  }
  buildHeap() {
    const arr = this.originArray;
    const startIndex = Math.floor(arr.length);
    for (let i = startIndex; i >= 1; i--) {
      this.heapify(arr, arr.length, i);
    }
    return arr;
  }

  heapify(arr, len, i) {
    while (true) {
      let maxPos = i;
      // 如果index i拥有叶左节点 并且左节点较大
      if (i * 2 <= len && arr[i] < arr[i * 2]) {
        maxPos = i * 2;
      }
      // 如果index i拥有叶右节点 与Max节点比较大小,选出父/左/右中最大的一个
      if (i * 2 + 1 <= len && arr[maxPos] < arr[i * 2 + 1]) {
        maxPos = i * 2 + 1;
      }
      if (maxPos === i) break; // 循环直到i节点为最大值
      this.swap(arr, i, maxPos); // 交换位置, 父节点为父/左/右中最大的一个
      i = maxPos; // i为左/右节点,并尝试向下查找更大的值
    }
  }

  sort() {
    const arr = this.buildHeap(); // 先建堆
    let len = arr.length - 1;
    while (len > 1) {
      this.swap(arr, 1, len); // 交换顶元素和最后一位。顶元素永远是最大的。
      len--;
      this.heapify(arr, len, 1); //剩下的元素重新建堆 直到len === 1 停止
    }
    console.log(arr);
  }

  swap(arr, i, max) {
    let temp = arr[i];
    arr[i] = arr[max];
    arr[max] = temp;
  }
}

const arr = [null];
let i = 0;
while (i <= 10) {
  const num = Math.floor(Math.random() * 100);
  arr.push(num);
  i++
}
const testHeap = new HeapSort(arr);
testHeap.sort();

` python 代码

import random

class HeapSort:
    def __init__(self, data):
        self.data = data
        print('input:', self.data)

    def buildHeap(self):
        n = len(self.data)
        for i in range(n//2, 0, -1):
            self.heapify(n-1, i)
    def heapify(self,length, i):
        while True:
            maxPos = i
            if i * 2 <= length and self.data[i*2] > self.data[maxPos]:
                maxPos = i*2
            if i * 2 + 1 <= length and self.data[i*2 + 1] > self.data[maxPos]:
                maxPos = i*2 + 1
            if i == maxPos:
                break
            self.data[maxPos], self.data[i] = self.data[i], self.data[maxPos]
            i = maxPos
    def sort(self):
        self.buildHeap()
        n = len(self.data) - 1
        while n > 0:
            self.data[n],self.data[1] = self.data[1], self.data[n]
            n -= 1
            self.heapify(n, 1)

arr = [None]
i = 0
while i <= 10:
    num = random.randint(0, 99)
    arr.append(num)
    i += 1

test_heap = HeapSort(arr)
# test_heap.insert(50)  # Insert a new element (50)
test_heap.sort()
print(test_heap.data)