数据结构---手撕图解堆 下

简介: 数据结构---手撕图解堆 下

向下调整算法

首先声明这个算法的使用条件,该算法适用于除了堆顶外的其他部分都满足小堆或大堆的条件时,可以使用,简单来说就是pop堆顶的时候可以使用

使用的原理也相当简单,假设我们这里是小堆,那么堆顶元素被弹出,此时堆中第二小的元素一定是这个堆顶元素的儿子,那么我们就让堆的最后一个叶子来充当这个新的堆顶,这样可以在保持堆整体的构造不变的前提下还能把堆顶元素弹出,紧接着就让这个堆顶元素和下面的儿子进行比较,谁小谁就是新的堆顶,进行交换后第二小的元素就产生了,当然,如果树的高度很高,那么交换后可能需要继续交换,知道这个叶子回到最后一层,这个过程也是可以借助循环实现的,借助这个向下调整算法就可以把堆顶元素弹出的同时还能变成一个新堆,不断的找出最小的值或最大的值

那么下面我们来实现这个算法

void AdjustDown(HP* php, int n, int parent)
{
   
    assert(php);
    int child = parent * 2 + 1;
    while (child < n)
    {
   
        if (child + 1 < n && php->a[child + 1] < php->a[child])
        {
   
            child++;
        }
        if (php->a[child] < php->a[parent])
        {
   
            Swap(&php->a[child], &php->a[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
   
            break;
        }
    }
}
void HeapPop(HP* php)
{
   
    assert(php);
    Swap(&php->a[0], &php->a[php->size - 1]);
    php->size--;

    AdjustDown(php, php->size, 0);
}

堆的应用

堆排序即利用堆的思想来进行排序,总共分为两个步骤:

  1. 建堆
    升序:建大堆
    降序:建小堆
  2. 利用堆删除思想来进行排序
    建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。
    TOP-K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。
    比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。
    对于Top-K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能
    数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:
  3. 用数据集合中前K个元素来建堆
    前k个最大的元素,则建小堆
    前k个最小的元素,则建大堆
  4. 用剩余的N-K个元素依次与堆顶元素来比较,不满足则替换堆顶元素
    剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。
void PrintTopK(int* a, int n, int k)
{
   
// 1. 建堆--用a中前k个元素建堆
// 2. 将剩余n-k个元素依次与堆顶元素交换,不满则则替换
}
void TestTopk()
{
   
int n = 10000;
int* a = (int*)malloc(sizeof(int)*n);
srand(time(0));
for (size_t i = 0; i < n; ++i)
{
   
a[i] = rand() % 1000000;
}
a[5] = 1000000 + 1;
a[1231] = 1000000 + 2;
a[531] = 1000000 + 3;
a[5121] = 1000000 + 4;
a[115] = 1000000 + 5;
a[2335] = 1000000 + 6;
a[9999] = 1000000 + 7;
a[76] = 1000000 + 8;
a[423] = 1000000 + 9;
a[3144] = 1000000 + 10;
PrintTopK(a, n, 10);
}
相关文章
|
7天前
|
存储 算法
【数据结构】堆
【数据结构】堆
|
1月前
|
算法 安全 大数据
揭秘!Python堆与优先队列:数据结构的秘密武器,让你的代码秒变高效战士!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能,助你提升算法效率。堆用于快速找大数据集的第K大元素,如示例所示,时间复杂度O(n log k)。PriorityQueue在多线程中智能调度任务,如模拟下载管理器,按优先级处理任务。掌握这些工具,让代码运行更高效!
49 1
|
6天前
|
存储 算法 Linux
【数据结构】树、二叉树与堆(长期维护)(1)
【数据结构】树、二叉树与堆(长期维护)(1)
|
12天前
|
搜索推荐 算法 Go
深入探索堆:Go语言中的高效数据结构
深入探索堆:Go语言中的高效数据结构
|
6天前
|
算法
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
|
11天前
【数据结构】二叉树顺序实现(大堆)-->赋源码
【数据结构】二叉树顺序实现(大堆)-->赋源码
25 4
|
1月前
|
存储 算法
【数据结构】堆,堆的实现,堆排序,TOP-K问题
数据结构——堆,堆的实现,堆排序,TOP-K问题
22 1
【数据结构】堆,堆的实现,堆排序,TOP-K问题
|
1天前
|
算法
【初阶数据结构篇】堆的应用(堆排序与Top-K问题)
即求数据结合中前K个最⼤的元素或者最⼩的元素,⼀般情况下数据量都⽐较⼤。
|
1天前
|
存储 算法 测试技术
【初阶数据结构篇】实现顺序结构二叉树(堆的实现方法)
注意传过去的参数是插入的位置,即插入前的size,在调整完后再将size++
|
5天前
|
存储
全局变量和局部变量在堆和栈的区别
全局变量和局部变量在堆和栈的区别
13 0