堆的基础操作,C语言示例

#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 && arrleft > arrlargest)

largest = left;

if (right < n && arrright > arrlargest)

largest = right;

if (largest != i) {

swap(&arri, &arrlargest);

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 && arri > arr(i - 1) / 2) {

swap(&arri, &arr(i - 1) / 2);

i = (i - 1) / 2;

}

}

// 删除堆顶元素

void deleteTop(int arr\[\], int* n) {

if (*n <= 0) {

printf("堆为空,无法删除!\n");

return;

}

// 用最后一个元素替换堆顶,再向下调整

arr0 = arr\*n - 1;

(*n)--;

heapify(arr, *n, 0);

}

// 获取堆顶元素

int getTop(int arr\[\], int n) {

if (n <= 0) {

printf("堆为空!\n");

return -1; // 无效值标记

}

return arr0;

}

// 修改堆中元素

void updateValue(int arr\[\], int n, int index, int newValue) {

if (index < 0 || index >= n) {

printf("索引无效!\n");

return;

}

int oldValue = arrindex;

arrindex = newValue;

if (newValue > oldValue) {

// 新值更大,向上调整

while (index > 0 && arrindex > arr(index - 1) / 2) {

swap(&arrindex, &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 ", arri);

}

printf("\n");

}

int main() {

int heapMAX_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;

}

相关推荐
wuqingshun3141597 小时前
MYSQL的乐观锁和悲观锁是什么?
java
Jerry7 小时前
LeetCode 101. 对称二叉树
算法
唐青枫8 小时前
Java SLF4J 实战指南:从日志门面到 Logback、MDC 和链路追踪
java
jvmind_dev8 小时前
Java GC 实战指南(番外篇):被忽视的隐形杀手 —— Class Unloading 如何拖垮 GC
java·后端
可编程芯片开发8 小时前
基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真
算法
An_s8 小时前
机器学习python之识别图中物品信息
java·linux·开发语言
AI科技星8 小时前
线性算子不是空间映射函数,是全域双螺旋场之间拉伸、旋转、耦合、坍缩的跨空间标准化变换载体《全域数学vs传统数学:人类文明进阶200讲》第80讲
线性代数·算法·矩阵·数据挖掘·回归·乖乖数学·全域数学
米罗篮8 小时前
矩阵快速幂 (Exponentiation By Squaring Applied To Matrices)
c++·线性代数·算法·矩阵
dream_home84078 小时前
图像算法模型NPU适配与算法服务实战指南
人工智能·python·算法·npu 图像服务
AIGS0019 小时前
跨越语义鸿沟:企业本体语义平台的构建与落地
java·人工智能·python·机器学习·人工智能ai大模型应用