面试题答案
一键面试构建初始堆的步骤
- 确定堆的类型:这里以大顶堆为例。大顶堆要求每个节点的值都大于或等于其左右子节点的值。
- 从最后一个非叶子节点开始:对于一个具有
n
个元素的数组arr
,最后一个非叶子节点的索引为(n - 2) / 2
。 - 进行堆化操作:从最后一个非叶子节点开始,依次向前对每个节点进行堆化操作。堆化操作的目的是将以该节点为根的子树调整为大顶堆。在堆化过程中,比较当前节点与其子节点的值,如果子节点的值大于当前节点的值,则交换它们,然后递归地对被交换的子节点进行堆化,确保子树也满足大顶堆的性质。
C语言代码片段
#include <stdio.h>
// 交换两个数
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 堆化操作,将以 i 为根的子树调整为大顶堆
void heapify(int arr[], int n, int i) {
int largest = i; // 初始化最大元素为根节点
int left = 2 * i + 1; // 左子节点索引
int right = 2 * i + 2; // 右子节点索引
// 如果左子节点比根节点大
if (left < n && arr[left] > arr[largest])
largest = left;
// 如果右子节点比最大元素大
if (right < n && arr[right] > arr[largest])
largest = right;
// 如果最大元素不是根节点
if (largest != i) {
swap(&arr[i], &arr[largest]);
// 递归地堆化受影响的子树
heapify(arr, n, largest);
}
}
// 构建初始大顶堆
void buildMaxHeap(int arr[], int n) {
// 从最后一个非叶子节点开始,依次向前堆化
for (int i = (n - 2) / 2; i >= 0; i--)
heapify(arr, n, i);
}
你可以使用以下方式调用这些函数:
int main() {
int arr[] = {4, 10, 3, 5, 1};
int n = sizeof(arr) / sizeof(arr[0]);
buildMaxHeap(arr, n);
printf("构建后的大顶堆: ");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}