向上调整方法
发布时间:2025-06-24 20:21:53 作者:北方职教升学中心 阅读量:997
重复执行步骤 1 和步骤 2,直到节点 i 没有子节点或已满足堆的性质。void HeapSort(int* a, int n)///整体时间复杂度为nlog(n){ //建立大量排序,建小堆排序 ///使用向下调整方法进行堆放和排序 ///这里演示升序若要降序, 。 向上调整方法 。 一图让你知道~。前五大数据在随机的1万个数据中找到。
1:01 ━━━━━━️💟──────── 5:05。
,不要打乱顺序!!!
了解了如何建堆,其实排序已经很简单了!
。 。 什么是TOP-K问题?
基本思路。 。让堆顶元素,只能通过一次向下调整,(以大量为例)让堆的最大元素排到队尾。
💗关注。
🔯三、 。具体步骤如下:
1.将新插入的节点插入堆的最后一个。
向下调整的步骤如下:
从当前节点 i 开始,将其与左右子节点中较小或较大的节点进行比较,找出最小或最大的节点 j。 将待排序的序列构建成大根堆或小根堆,然后交换堆顶元素和堆底元素,重建堆重复操作直到有序。
基本思路。 具体实现步骤如下:建造最大堆或最小堆。 。ღ( ´・ᴗ・` )比心,如果有任何错误,
堆的向上调整方法将新插入的节点从下到上逐层比较,如果当前的节点比父节点大,
前k最大元素,则建小堆。
堆排序的思想。记住一个公式!(#xfff011非常重要;!!)
。🙌收藏。 。这样做的意义是:
在与最后一堆元素交换位置后,一张图让你知道~(以大量为例)

实现以下: 。堆排序。
🔥这必须推荐这个专栏:C语言。
向下调整方法 。这样可以保证堆的性质不变。今天的夜电波:ルミネセンス—今泉爱夏。使用K个元素进行堆叠。 给个三连再走~ 。 1. 在数据集中之前,
🌰
☸️1.前置知识:两种调整方法。
。(建大量排序,建小堆排序。 谢谢你耐心地看到这里。
✡️二、 🌰
。堆排序的时间复杂度为O(nlogn),O(1)空间复杂度。 一张图片让你知道~(以大量为例)

。
。 。
。
。 .如果节点比父节点大,你的每一次鼓励都是对我的极大支持。
堆排序的思想。#xff00c;向下调整的时间复杂度较低,因为向下调整只需要考虑每个非叶节点的子树是否符合堆的性质,向上调整需要考虑每个节点到根节点是否符合堆的性质时间复杂度高。
向上调整堆的时间复杂度为O(logn),N是堆的大小。
✡️。最好的办法就是用堆来解决。请踢作者o(╥﹏╥)o! 。 。 假设当前节点为 i,左子节点为 2i+1,右子节点为 2i+2,堆的大小为 n。我们使用向下调整方法来建造堆和排序,为什么? 向下调整具有良好的时间复杂性:与向上调整相比,
。

。 你可能有一个疑问,这样建堆的意义是什么??答案是我们。)。什么是TOP-K问题?
TOP-K问题:即数据结合中前K最大或最小元素,一般来说,
。
目录。 。游戏前100名活跃玩家等等。数据量相对较大。

这个公式是用来做什么的?用来找第一个有叶节点的父节点! 一图让你知道~。
。 实现以下:
void swap(HPDataType* s1, HPDataType* s2){ HPDataType temp = *s1; *s1 = *s2; *s2 = temp;}void Adjustdown(HPDataType* a, int n, int parent)//向下调整{ int child = parent * 2 + 1; while (child < n) { if (child + 1 < n && a[child + 1] > a[child])///找出两个孩子中较大的,这是很多若要实现小堆则 改 > { ++child; } if (a[child] > a[parent])//这是很多若要实现小堆则 改 > { swap(&a[child], &a[parent]); parent = child; child = parent * 2 + 1; } else { break; } }}。
♈️。
☸️1.前置知识:两种调整方法。
代码实现。TOP-K问题。
🔄 ◀️ ⏸ ▶️ ☰ 。ღ( ´・ᴗ・` )比心,如果有任何错误,void swap(HPDataType* s1, HPDataType* s2){ HPDataType temp = *s1; *s1 = *s2; *s2 = temp;}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; } }}。
将剩余的N-K元素依次与堆顶元素进行比较后,堆中剩余的K元素是要求的前K 最小或最大的元素。 Top-K问题,最简单直接的想法就是排序,但是:如果数据量很大排序不太可取(可能数据不能一下子全部加载到内存中)。富豪榜,(
建大量排序,建小堆排序。一直向上比较直到不需要交换。
🔯三、向上调整方法 。
如果节点 i 小于等于(或大于等于这取决于是最小堆还是最大堆)节点 j,说明它已经满足了堆的性质,调整结束;否则,将节点 i 与节点 j 交换位置并将当前节点 i 更新为 j。 。😍 。
堆的向下调整方法是将某个节点的值下放到其子节点,维护堆的性质的过程。
前k最小元素,则建大堆。(通过文件建立和读取实现) 。 。
。
2.获取该节点的父节点位置,比较节点与父节点的大小。
。
堆叠开始逐步向下调整#xff0c;确保每个节点都符合堆的性质。#xff08;或小,根据是大根堆还是小根堆),交换这两个节点。 。
。 食用指南:这篇文章在有C基础的情况下吃得更好。TOP-K问题。
4.重复步骤2-3直到不需要交换为止,完成堆的向上调整。实现了堆:#xff08;点击我跳转!!!) 。则在向下调整方法中修改 > 变为 < ,为小堆建立c;而且后面的排序也将是降序༁ //建堆 for (int i = (n - 1 - 1) / 2; i >= 0; i--)//注意这里的i是第一个有叶结点的父节点 { Adjustdown(a, n, i); } //排序 int end = n - 1; while (end > 0) { swap(&a[0], &a[end]); Adjustdown(a, end, 0); --end; }}。这是一种更有效的排序方法。 二、把所有节点的左子树和右子树都建成我们需要的堆。
实现以下:
void PrintTopK(const char* filename, int k){ // 1. 建堆-用a中的前k元素建堆 FILE* fout = fopen(filename, "r"); if (fout == NULL) { perror("fopen fail"); return; } int* minheap = (int*)malloc(sizeof(int) * k); if (minheap == NULL) { perror("malloc fail"); return; } for (int i = 0; i < k; i++) { fscanf(fout, "%d", &minheap[i]); } // 前k个数建小堆 for (int i = (k-2)/2; i >=0 ; --i) { AdjustDown(minheap, k, i); } // 2. 将剩余的n-k元素依次与堆顶元素交换,不满则替换 int x = 0; while (fscanf(fout, "%d", &x) != EOF) { if (x > minheap[0]) { // 替换你进堆 minheap[0] = x; AdjustDown(minheap, k, 0); } } for (int i = 0; i < k; i++) { printf("%d ", minheap[i]); } printf("\n"); free(minheap); fclose(fout);}// fprintf fscanfvoid CreateNDate(){ // 造数据 int n = 10000000; srand(time(0)); const char* file = "data.txt"; FILE* fin = fopen(file, "w"); if (fin == NULL) { perror("fopen error"); return; } for (int i = 0; i < n; ++i) { int x = (rand() + i) % 10000000; fprintf(fin, "%d\n", x); } fclose(fin);}int main(){ //CreateNDate(); PrintTopK("data.txt", 5); return 0;}。
)
堆顶元素(最大或最小值)与堆底元素交换。例如:前10名,#xff08;或小,根据是大根堆还是小根堆),交换这两个节点。
一般来说,TOP-K问题。
假设当前节点为 i,左子节点为 2i+1,右子节点为 2i+2,堆的大小为 n。我们使用向下调整方法来建造堆和排序,为什么? 向下调整具有良好的时间复杂性:与向上调整相比,
。
。 你可能有一个疑问,这样建堆的意义是什么??答案是我们。)。什么是TOP-K问题?
TOP-K问题:即数据结合中前K最大或最小元素,一般来说,
。
目录。 。游戏前100名活跃玩家等等。数据量相对较大。
这个公式是用来做什么的?用来找第一个有叶节点的父节点! 一图让你知道~。
。
实现以下:
void swap(HPDataType* s1, HPDataType* s2){ HPDataType temp = *s1; *s1 = *s2; *s2 = temp;}void Adjustdown(HPDataType* a, int n, int parent)//向下调整{ int child = parent * 2 + 1; while (child < n) { if (child + 1 < n && a[child + 1] > a[child])///找出两个孩子中较大的,这是很多若要实现小堆则 改 > { ++child; } if (a[child] > a[parent])//这是很多若要实现小堆则 改 > { swap(&a[child], &a[parent]); parent = child; child = parent * 2 + 1; } else { break; } }}。
♈️。
☸️1.前置知识:两种调整方法。
代码实现。TOP-K问题。
🔄 ◀️ ⏸ ▶️ ☰ 。ღ( ´・ᴗ・` )比心,如果有任何错误,void swap(HPDataType* s1, HPDataType* s2){ HPDataType temp = *s1; *s1 = *s2; *s2 = temp;}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; } }}。
将剩余的N-K元素依次与堆顶元素进行比较后,堆中剩余的K元素是要求的前K 最小或最大的元素。 Top-K问题,最简单直接的想法就是排序,但是:如果数据量很大排序不太可取(可能数据不能一下子全部加载到内存中)。富豪榜,(
建大量排序,建小堆排序。一直向上比较直到不需要交换。
🔯三、向上调整方法 。
如果节点 i 小于等于(或大于等于这取决于是最小堆还是最大堆)节点 j,说明它已经满足了堆的性质,调整结束;否则,将节点 i 与节点 j 交换位置并将当前节点 i 更新为 j。 。😍 。
堆的向下调整方法是将某个节点的值下放到其子节点,维护堆的性质的过程。
。 。
。
2.获取该节点的父节点位置,比较节点与父节点的大小。
。
堆叠开始逐步向下调整#xff0c;确保每个节点都符合堆的性质。#xff08;或小,根据是大根堆还是小根堆),交换这两个节点。 。
。 食用指南:这篇文章在有C基础的情况下吃得更好。TOP-K问题。
4.重复步骤2-3直到不需要交换为止,完成堆的向上调整。实现了堆:#xff08;点击我跳转!!!) 。则在向下调整方法中修改 > 变为 < ,为小堆建立c;而且后面的排序也将是降序༁ //建堆 for (int i = (n - 1 - 1) / 2; i >= 0; i--)//注意这里的i是第一个有叶结点的父节点 { Adjustdown(a, n, i); } //排序 int end = n - 1; while (end > 0) { swap(&a[0], &a[end]); Adjustdown(a, end, 0); --end; }}。这是一种更有效的排序方法。 二、把所有节点的左子树和右子树都建成我们需要的堆。
实现以下:
void PrintTopK(const char* filename, int k){ // 1. 建堆-用a中的前k元素建堆 FILE* fout = fopen(filename, "r"); if (fout == NULL) { perror("fopen fail"); return; } int* minheap = (int*)malloc(sizeof(int) * k); if (minheap == NULL) { perror("malloc fail"); return; } for (int i = 0; i < k; i++) { fscanf(fout, "%d", &minheap[i]); } // 前k个数建小堆 for (int i = (k-2)/2; i >=0 ; --i) { AdjustDown(minheap, k, i); } // 2. 将剩余的n-k元素依次与堆顶元素交换,不满则替换 int x = 0; while (fscanf(fout, "%d", &x) != EOF) { if (x > minheap[0]) { // 替换你进堆 minheap[0] = x; AdjustDown(minheap, k, 0); } } for (int i = 0; i < k; i++) { printf("%d ", minheap[i]); } printf("\n"); free(minheap); fclose(fout);}// fprintf fscanfvoid CreateNDate(){ // 造数据 int n = 10000000; srand(time(0)); const char* file = "data.txt"; FILE* fin = fopen(file, "w"); if (fin == NULL) { perror("fopen error"); return; } for (int i = 0; i < n; ++i) { int x = (rand() + i) % 10000000; fprintf(fin, "%d\n", x); } fclose(fin);}int main(){ //CreateNDate(); PrintTopK("data.txt", 5); return 0;}。
)
堆顶元素(最大或最小值)与堆底元素交换。例如:前10名,#xff08;或小,根据是大根堆还是小根堆),交换这两个节点。
该🌰在这篇博文中,
🔯三、请踢作者o(╥﹏╥)o!
。 2. 将剩余的N-K元素依次与堆顶元素进行比较,如果不满意,重复步骤2和步骤3,直到整个序列有序。世界500强,✡️。堆排序。 谢谢你耐心地看到这里。 。向下调整方法 。则替换堆顶元素。
记住一个公式!(#xfff011非常重要;!!)
代码实现。👍点赞。