首页 > 其他分享 >堆的应用

堆的应用

时间:2024-09-17 11:01:58浏览次数:9  
标签:堆化 nums int maxIdx heapIdx 应用 节点

1.需要具备的知识

1.1以顺序存储方式存储完全二叉树

完全二叉树:节点从上到下,从左到右布局的二叉树,如下图所示。


完全二叉树可以使用类似数组这种顺序存储的结构存节点,如下图。


按照"层级遍历"方式遍历这棵树(还有"前序、中序、后序"遍历方式,这里不做介绍),遍历结果"10->5->1->2->3->6"保存到数组中。为了方便计算父子节点对应关系,不使用数组第一个元素。
如果一个节点在数组中的下标是curIdx,那么如果存在,其对应的左右孩子节点下标lcIdx,rcIdx,以及对应的父节点下标pIdx分别为:

lcIdx=2*curIdx;
rcIdx=2*curIdx;
pIdx=curIdx/2;

1.2堆介绍

堆是一种特殊的完全二叉树,分为大顶堆和小顶堆。大顶堆满足每个节点的值都大于或等于其孩子节点的值;小顶堆满足每个节点的值都小于或等于其孩子节点的值。如下图所示,以下部分我们全部以大顶堆为例

1.3堆化和建堆

堆化是指将某一个节点放到正确的位置,使得这个节点满足堆的属性。分为两种方式:从下向上堆化和从上向下堆化。

1.3.1从下向上堆化

使用场景是将元素一个一个插入到堆中,先将新元素做为叶子节点放到最后位置,然后将该节点向上堆化,最终落到满足堆特性的位置,如下图所示。
1.新节点值为9,先放入到最后位置。
2.9大于其父节点8,交换两个节点。
3.新的9节点继续和其父节点比较,小于10,堆化结束。

代码实现如下,nums存储的是堆节点数据。

//从下往上堆化一个节点
void HeapifyFromBToUp(vector<int>&nums,int heapIdx)
{
    while(heapIdx>1) //heapIdx为1的根节点没有父节点,故不用再处理
    {
        if(nums[heapIdx]>nums[heapIdx/2])//当前堆化节点的值大于其父节点的值
        {
            //交换两个节点的值
            int temp = nums[heapIdx/2];
            nums[heapIdx/2]=nums[heapIdx];
            nums[heapIdx]=temp;
            heapIdx = heapIdx/2;//继续向上堆化
        }
        else
        {
            //当前堆化节点在正确位置,堆化结束
            break;
        }
    }
}
void insertIntoHeap(vector<int>&nums,int value)
{
    nums.push_back(value);//先将新节点插入到最后
    HeapifyFromBToUp(nums,nums.size()-1);//对新节点向上堆化
}

1.3.2从上向下堆化

使用场景是将已经存在的完全二叉树,从最后一个非叶子节点开始,将该节点向下堆化,最终落到满足堆特性的位置,如下图所示。最后一个非叶子节点下标为数组长度/2,这里为7/2=3。
1.节点6小于其唯一的左孩子节点9,二者交换,节点6堆化完成。
2.节点3与其左右两个节点比较,三个节点最大是10,交换10节点和3节点,节点3堆化完成。
3.节点5与其左右两个节点比较,三个节点最大是10,交换10节点和5节点,节点5堆化完成。至此,所有节点堆化完成。

代码实现如下:nums存储的是树节点数据。

//从上向下堆化一个节点heapIdx,这里的n在排序时有用,后面讲解。
 void HeapifyFromUpToB(vector<int>&nums,int n,int heapIdx)
   {
      int size = n;
      int temp=0;
      while(true)
      {
          //找到堆化节点heapIdx和其左右孩子节点中的最大值
          int maxIdx = heapIdx;
          if(2*heapIdx<size && nums[2*heapIdx]>nums[maxIdx])
              maxIdx = 2*heapIdx;
           if(2*heapIdx+1<size && nums[2*heapIdx+1]>nums[maxIdx])
              maxIdx = 2*heapIdx+1;
           if(maxIdx==heapIdx)//堆化节点位置正确,堆化结束
              break;
          //交换堆化节点和最大值节点
          temp=nums[heapIdx];
          nums[heapIdx]=nums[maxIdx];
          nums[maxIdx]=temp;
          //
          heapIdx=maxIdx; //如果只是构建堆可以不用这行,但是在排序时有用,后面讲解(巧妙) 
      }
  }
    //建堆
    void heapBuilder(vector<int>&nums)
    {
        int size = nums.size();
        //
        for(int i=size/2;i>=1;--i)
            HeapifyFromUpToB(nums,size,i);//逐个堆化非叶子节点
    }

2.应用-查找topK

在大量数据文件中找到第K小的那个数据,可能是GB或TB级别的数据量。如果先实现排序再返回第K小的数据,占用内存空间复杂度太高O(n),如果用快排等思想,时间复杂度为O(nlogn),这种方法不合适。
我们可以维护一个大小为K的大顶堆,这个大顶堆的目的是存储前K小的数据。遍历数据文件,
1.如果新数据比栈顶小则说明当前栈顶肯定不满足前K小,将当前栈顶元素更新为新数据,并对新栈顶节点进行堆化处理。因为是对栈顶节点堆化,只能用从上向下的堆化方式
2.如果新数据不比栈顶元素小,则不做处理。
相信有了上面建堆和堆化的方法,不难实现该功能,这里不再列出源代码了。

3.应用-排序

大顶堆满足每个节点的值都不小于其孩子节点的值,栈顶节点是最大值。利用栈的这种特性我们可以很方便的完成排序工作:
1.将栈顶和最后的叶子节点交换。
2.对新的栈顶进行堆化(旧栈顶不在堆化范围),由于是栈顶堆化,所以必须使用从上向下堆化
3.重复1、2直到将最后一个新栈顶元素堆化完成结束。

标签:堆化,nums,int,maxIdx,heapIdx,应用,节点
From: https://www.cnblogs.com/madadam/p/18411128

相关文章

  • 大数据技术原理与应用——从入门到文档数据库
    大数据技术原理与应用3次信息化的浪潮研究问题的四个阶段大数据技术的层次大数据的计算模式PaaS物联网的概念云计算、大数据、物联网之间的关系Hadoop应用现状选择Hdoop需要考虑的因素Hadoop的定量评分(满分为5分)总体评价Ubuntu的一些基本知识(之所以不......
  • MySQL中的ON DUPLICATE KEY UPDATE详解与应用
    目录什么是ONDUPLICATEKEYUPDATE?ONDUPLICATEKEYUPDATE的基本语法适用场景及工作原理使用ONDUPLICATEKEYUPDATE的实际示例示例1:简单的插入和更新示例2:结合多列唯一约束示例3:动态更新某些字段性能分析与优化建议与REPLACEINTO的区别注意事项与常见问题......
  • 【架构设计】多级缓存:应用案例与问题解决策略
    【架构设计】多级缓存:应用案例与问题解决策略多级缓存系统的工作原理及其在提升应用性能方面的关键作用。通过对比本地缓存与分布式缓存的特点| 原创作者/编辑:凯哥Java                    | 分类:架构设计系列教程多级缓存系统:提升性能的......
  • 人工智能--运维应用
    最近在和小伙伴们探讨人工智能的一些方案,突发奇想,是否在网络传输中也能用到人工智能来解决现实中现象级的一些问题呢。目前我们大大小小的项目建设,常规到安防监控项目、机房项目、工业自动化项目、电子警察、、警察。。。等等,太多了,都和网络有着直接的关系,但实际在项目运维阶段,问......
  • 【架构设计】多级缓存:应用案例与问题解决策略
      【架构设计】多级缓存:应用案例与问题解决策略 多级缓存系统的工作原理及其在提升应用性能方面的关键作用。通过对比本地缓存与分布式缓存的特点 | 原创作者/编辑:凯哥Java                    | 分类:架构设计系列教程 ......
  • macOS Sequoia 15 发布,iPhone 镜像、密码应用程序、窗口平铺更新等带来全新体验
    macOSSequoia15发布,iPhone镜像、密码应用程序、窗口平铺更新等带来全新体验2024年9月17日凌晨1点请访问原文链接:https://sysin.org/blog/macOS-Sequoia/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgTimCook领导的Apple今天发布了macOS15Sequoia......
  • C:\Users\用户名\AppData\Roaming\ 是 Windows 操作系统中的一个特殊文件夹,用于
    C:\Users\用户名\AppData\Roaming\是Windows操作系统中的一个特殊文件夹,用于存储应用程序的数据和设置。这个文件夹通常用于存放用户级别的应用程序配置文件、数据文件和其他需要在用户登录时保留的信息。这里的路径分为几个部分:C:\Users\用户名\:这是当前用户的主文件夹路......
  • 【智能算法应用】粒子群算法求解最小生成树问题
    目录1.最小生成树MST2.算法原理3.算法过程4.结果展示5.参考文献6.代码获取1.最小生成树MST最小生成树(MinimumSpanningTree,MST)是在给定的加权无向图中寻找一个边的子集,使得这些边构成的树包含图中的所有顶点,并且边的总权重尽可能小。如果图......
  • 【智能算法应用】海洋捕食者算法求解TSP问题
    目录1.算法原理2.TSP数学模型3.结果展示4.参考文献5.代码获取1.算法原理【智能算法】海洋捕食者算法(MPA)原理及实现2.TSP数学模型旅行商问题(TSP)是一种著名的组合优化问题,它涉及寻找给定一组城市及其之间的距离或成本,如何规划一条最短的路径,使得旅行商从起点出发,......
  • 【智能算法应用】飞蛾扑火算法求解TSP问题
    目录1.算法原理2.TSP数学模型3.结果展示4.参考文献5.代码获取1.算法原理【智能算法】飞蛾扑火算法(MFO)原理及实现2.TSP数学模型旅行商问题(TSP)是一种著名的组合优化问题,它涉及寻找给定一组城市及其之间的距离或成本,如何规划一条最短的路径,使得旅行商从起点出发,访......