#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100 // 堆的最大容量
// 交换两个元素
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 堆调整(向下调整,维护大顶堆)
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 buildHeap(int arr[], int n) {
// 从最后一个非叶子节点开始向前调整
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
}
// 插入元素
void insert(int arr[], int* n, int value) {
if (*n >= MAX_SIZE) {
printf("堆已满,无法插入!\n");
return;
}
// 新元素放到末尾,再向上调整
arr[*n] = value;
int i = *n;
(*n)++;
// 与父节点比较,大于则交换
while (i > 0 && arr[i] > arr[(i - 1) / 2]) {
swap(&arr[i], &arr[(i - 1) / 2]);
i = (i - 1) / 2;
}
}
// 删除堆顶元素
void deleteTop(int arr[], int* n) {
if (*n <= 0) {
printf("堆为空,无法删除!\n");
return;
}
// 用最后一个元素替换堆顶,再向下调整
arr[0] = arr[*n - 1];
(*n)--;
heapify(arr, *n, 0);
}
// 获取堆顶元素
int getTop(int arr[], int n) {
if (n <= 0) {
printf("堆为空!\n");
return -1; // 无效值标记
}
return arr[0];
}
// 修改堆中元素
void updateValue(int arr[], int n, int index, int newValue) {
if (index < 0 || index >= n) {
printf("索引无效!\n");
return;
}
int oldValue = arr[index];
arr[index] = newValue;
if (newValue > oldValue) {
// 新值更大,向上调整
while (index > 0 && arr[index] > arr[(index - 1) / 2]) {
swap(&arr[index], &arr[(index - 1) / 2]);
index = (index - 1) / 2;
}
} else {
// 新值更小,向下调整
heapify(arr, n, index);
}
}
// 判断堆是否为空
int isEmpty(int n) {
return n == 0;
}
// 打印堆
void printHeap(int arr[], int n) {
if (isEmpty(n)) {
printf("堆为空\n");
return;
}
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int heap[MAX_SIZE]; // 存储堆的数组
int size = 0; // 当前堆的大小
// 演示1:插入元素
printf("=== 插入元素 ===\n");
insert(heap, &size, 10);
insert(heap, &size, 30);
insert(heap, &size, 20);
insert(heap, &size, 50);
insert(heap, &size, 40);
printf("插入后堆的内容:");
printHeap(heap, size); // 输出:50 40 20 10 30
// 演示2:获取堆顶元素
printf("\n=== 获取堆顶 ===\n");
printf("当前堆顶(最大值):%d\n", getTop(heap, size)); // 输出:50
// 演示3:删除堆顶
printf("\n=== 删除堆顶 ===\n");
deleteTop(heap, &size);
printf("删除后堆的内容:");
printHeap(heap, size); // 输出:40 30 20 10
// 演示4:修改元素
printf("\n=== 修改元素 ===\n");
printf("将索引2的元素(值为20)修改为60:\n");
updateValue(heap, size, 2, 60);
printf("修改后堆的内容:");
printHeap(heap, size); // 输出:60 30 40 10(因为60>20,向上调整)
// 演示5:用无序数组创建堆
printf("\n=== 用无序数组创建堆 ===\n");
int arr[] = {1, 3, 2, 5, 4};
int n = 5;
buildHeap(arr, n);
printf("创建的堆内容:");
printHeap(arr, n); // 输出:5 4 2 3 1
return 0;
}