📜  从数组构建堆(1)

📅  最后修改于: 2023-12-03 15:06:36.134000             🧑  作者: Mango

从数组构建堆

在计算机科学中,堆是一种经典的数据结构,被广泛应用于算法和程序设计中。堆可以看作是一颗完全二叉树,树上的每个节点都比其子节点(如果有的话)大或小,我们称之为最小堆和最大堆。在本文中,我们将探讨如何从数组构建堆。

构建最小堆

最小堆的特点是根节点的值最小,我们可以按以下步骤从数组构建最小堆:

  1. 从数组第一个非叶子节点开始,向上遍历每个非叶子节点。
  2. 对于每个非叶子节点,将其与其子节点进行比较,如果该节点的值比其子节点大,则交换这两个节点的值。
  3. 重复步骤2,直到该节点的值不再比其子节点大,或者该节点成为叶子节点。

下面是一段JavaScript代码,演示了如何从数组构建最小堆:

function buildMinHeap(arr) {
  for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
    heapify(arr, i, arr.length);
  }
}

function heapify(arr, i, length) {
  let left = 2 * i + 1;
  let right = 2 * i + 2;
  let smallest = i;

  if (left < length && arr[left] < arr[smallest]) {
    smallest = left;
  }

  if (right < length && arr[right] < arr[smallest]) {
    smallest = right;
  }

  if (smallest !== i) {
    [arr[i], arr[smallest]] = [arr[smallest], arr[i]];
    heapify(arr, smallest, length);
  }
}

这段代码首先定义了两个函数,buildMinHeap和heapify,分别用于构建最小堆和维护堆的性质。buildMinHeap函数接受一个数组作为参数,将该数组构建成最小堆。

在buildMinHeap函数中,我们从最后一个非叶子节点开始,向上遍历每个非叶子节点,调用heapify函数,维护堆的性质。

在heapify函数中,我们通过左右子节点的比较,找到较小的节点,并将其与该节点交换。如果该节点的值发生了变化,则继续向下递归heapify函数,直到该节点的值不再比其子节点小,或者该节点成为叶子节点。

构建最大堆

最大堆的特点是根节点的值最大,我们可以按以下步骤从数组构建最大堆:

  1. 从数组第一个非叶子节点开始,向上遍历每个非叶子节点。
  2. 对于每个非叶子节点,将其与其子节点进行比较,如果该节点的值比其子节点小,则交换这两个节点的值。
  3. 重复步骤2,直到该节点的值不再比其子节点小,或者该节点成为叶子节点。

下面是一段JavaScript代码,演示了如何从数组构建最大堆:

function buildMaxHeap(arr) {
  for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
    heapify(arr, i, arr.length);
  }
}

function heapify(arr, i, length) {
  let left = 2 * i + 1;
  let right = 2 * i + 2;
  let largest = i;

  if (left < length && arr[left] > arr[largest]) {
    largest = left;
  }

  if (right < length && arr[right] > arr[largest]) {
    largest = right;
  }

  if (largest !== i) {
    [arr[i], arr[largest]] = [arr[largest], arr[i]];
    heapify(arr, largest, length);
  }
}

这段代码与构建最小堆的代码类似,不同之处在于heapify函数中,我们通过左右子节点的比较,找到较大的节点,并将其与该节点交换。如果该节点的值发生了变化,则继续向下递归heapify函数,直到该节点的值不再比其子节点大,或者该节点成为叶子节点。

结语

堆是一种经典的数据结构,它的应用非常广泛,如堆排序、优先队列等。通过本文介绍的方法,我们可以从数组构建堆,使得我们的程序更加高效和优雅。