当前位置: 首页 > news >正文

[数据结构]7. 堆-Heap

堆-Heap

  • 1. 介绍
  • 2. 堆的实现
  • 3. 堆操作
    • Initlilze
    • Destory
    • Swap
    • Push
    • Pop
    • Top
    • Empty
    • Size
    • AdjustUp
    • AdjustDown
  • 4. HeapSort
  • 5. Top-K

1. 介绍

堆(heap) 是一种满足特定条件的完全二叉树。

  • 小顶堆(min heap):任意节点的值 ≤ 其子节点的值。
  • 大顶堆(max heap):任意节点的值 ≥ 其子节点的值
    请添加图片描述

堆作为完全二叉树的一个特例,具有以下特性。

  • 最底层节点靠左填充,其他层的节点都被填满。
  • 将根节点称为“堆顶”,将底层最靠右的节点称为“堆底”。
  • 大顶堆,根节点值是最大的。
  • 小顶堆,根节点值是最小的。

2. 堆的实现

完全二叉树非常适合用数组来表示。
使用数组表示二叉树时,元素代表节点值,索引代表节点在二叉树中的位置。
节点指针通过索引映射公式来实现:
给定索引 𝑖 ,其左子节点的索引为 2𝑖 + 1 ,右子节点的索引为 2𝑖 + 2 ,父节点的索引为(𝑖 - 1)/2(向下整除)。当索引越界时,表示空节点或节点不存在。
请添加图片描述

3. 堆操作

Initlilze

void HeapInit(HP* php) {assert(php);php->a = NULL;php->size = 0;php->capacity = 0;
}

Destory

void HeapDestory(HP* php) {assert(php);free(php->a);php->a = NULL;php->capacity = 0;php->size = 0;
}

Swap

void Swap(HPDataType* p1, HPDataType* p2) {HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}

Push

请添加图片描述
请添加图片描述

void HeapPush(HP* php, HPDataType x) {assert(php);if (php->size == php->capacity) {int newCapacity = php->capacity == 0 ? 4 : php->capacity * 2;HPDataType* tmp = (HPDataType*)realloc(php->a, newCapacity * sizeof(HPDataType));php->a = tmp;php->capacity = newCapacity;}php->a[php->size] = x;php->size++;AdjustUp(php->a, php->size - 1);//向上排序
}

Pop

请添加图片描述

请添加图片描述

void HeapPop(HP* php) {assert(php);assert(!HeapEmpty(php));Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AdjustDown(php->a, php->size, 0);
}

Top

HPDataType HeapTop(HP* php) {assert(php);assert(!HeapEmpty(php));return php->a[0];
}

Empty

bool HeapEmpty(HP* php) {assert(php);return php->size == 0;
}

Size

int HeapSize(HP* php) {assert(php);return php->size;
}

AdjustUp

void AdjustUp(HPDataType* a, int child) {int parent = (child - 1) / 2;while (child > 0) {if (a[child] < a[parent]) {// 小堆Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else {break;}}
}

AdjustDown

void AdjustDown(HPDataType* a, int n, int parent) {// n为数据个数int child = parent * 2 + 1;while (child < n) {if (child + 1 < n && a[child] > a[child + 1]) {child++;}if (a[child] > a[parent]) {// maxSwap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}else {break;}}
}

4. HeapSort

void HeapSort(int* a, int n) {// 升序--建大堆 max// 建堆--向下调整堆--O(N)for (int i = (n - 1 - 1) / 2; i >= 0; --i) {AdjustDown(a, n, i);}int end = n - 1;while (end > 0) {Swap(&a[0], &a[end]);// 把堆顶max放在最后// 再调整,选出次小的,升序AdjustDown(a, end, 0);--end;}
}

5. Top-K

给定一个长度为 𝑛 的无序数组 nums ,请返回数组中最大的 𝑘 个元素。
Top‑k 是一个经典算法问题,可以使用堆数据结构高效解决,时间复杂度为 𝑂(𝑛 log 𝑘)
方案:

  1. 初始化一个小顶堆,其堆顶元素最小。
  2. 先将数组的前 𝑘 个元素依次入堆。
  3. 从第 𝑘 + 1 个元素开始,若当前元素大于堆顶元素,则将堆顶元素出堆,并将当前元素入堆。
  4. 遍历完成后,堆中保存的就是最大的 𝑘 个元素。

请添加图片描述

请添加图片描述

void CreateNData() {int n = 1000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");for (size_t i = 0; i < n; i++) {int x = rand() % 10000;fprintf(fin, "%d\n", x);}fclose(fin);
}
void PrintTopK(int k) {const char* file = "data.txt";FILE* fout = fopen(file, "r");int* kminheap = (int*)malloc(sizeof(int) * k);for (int i = 0; i < k; i++) {fscanf(fout, "%d", &kminheap[i]);}for (int i = (k - 1 - 1) / 2; i >= 0; i--) {AdjustDown(kminheap, k, i);}int val = 0;while (!feof(fout)) {//未到达文件末尾,feof返回零。fscanf(fout, "%d", &val);if (val > kminheap[0]) {kminheap[0] = val;AdjustDown(kminheap, k, 0);}}for (int i = 0; i < k; i++) {printf("%d ", kminheap[i]);}printf("\n");
}

相关文章:

  • 单片机-STM32部分:17、数码管
  • Elasticsearch 分片机制高频面试题(含参考答案)
  • 乡村农家游乐小程序源码介绍
  • 【测试工具】selenium和playwright如何选择去构建自动化平台
  • duxapp 2025-01-13 更新 支持小程序配置文件
  • STC8H系列单片机STC8H_H头文件功能注释
  • 【hot100-动态规划-300.最长递增子序列】
  • Vue3 本地环境 Vite 与生产环境 Nginx 反向代理配置方法汇总【反向代理篇】
  • Python多线程
  • 微信小程序医院挂号系统+SSM开发详解
  • conda更换清华源
  • 音频/AI/BLE/WIFI/玩具/商业等方向的论坛网站总结
  • 【愚公系列】《Manus极简入门》040-科技与组织升级顾问:“项目掌舵人”
  • Flutter——数据库Drift开发详细教程(六)
  • 讯联云库项目开发日志(二)AOP参数拦截
  • Profinet转Ethernet/IP网关模块通信协议适配配置
  • Ubuntu使用Docker搭建SonarQube企业版(含破解方法)
  • 奇妙协同效应,EtherNet IP与PROFINET网关优化半导体生产线
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: 注意“回车换行“的跨平台使用.
  • 【C++】Module CPP:模块化编程 Demo
  • 巴基斯坦与印度停火延长至18日
  • 最高人民法院、中国证监会联合发布《关于严格公正执法司法 服务保障资本市场高质量发展的指导意见》
  • 中国证券业协会修订发布《证券纠纷调解规则》
  • 中国—美国经贸合作对接交流会在华盛顿成功举行
  • 马上评|“衣服越来越难买”,对市场是一个提醒
  • 被前男友泼汽油致残后,一个女孩经历的双重灼烧