向上调整算法(详解)c++

算法流程:

  1. 与⽗结点的权值作⽐较,如果⽐它⼤,就与⽗亲交换;
  2. 交换完之后,重复 1 操作,直到⽐⽗亲⼩,或者换到根节点的位置

这里为什么插入85完后合法?

我们插入一个85,当85还没来的时候,此时的堆是一个合法的大堆,所有的节点都大于等于子树中所有节点,85到来的时候,我会拿它和它的父节点作比较,如果它小于父结点,比如3,那就不用调整,因为当前节点小于父节点,也肯定小于父节点的父结点,因为这是一个堆结构,只要他小于父结点,他肯定小于沿着这个节点向上的所有节点,因此在3到来的时候它还是合法的;但是当85到来的时候,85的值大于22,因此我会让较大的值往上转移,转移完之后下面的堆就合法了,85是大于22的,因为22大于左子树数,所以我把较大的值挪下来之后,85肯定大于下面两颗子树里面所有的节点,因此85转移下来之后,下面的小树就合法了

但是上面的我们还不确定,所以我们要继续拿85和上面的点做比较,当我们发现85比39还大的时候就继续转移,转移完之后下面的子树依旧是合法的,因为39没转移之前是大于它的左子树和右子树里面所有的点,所以当我把39转移到下面的时候,他依旧是大于20和22这两个点的,把39转移到下面的子树是不受影响的,但是当我把85转移到上面的红圈中的子树就合法了,原因就是刚刚85是比39大的,85转移到上面之后,85肯定是大于刚刚左子树里面所有的节点,以及刚刚右子树里面所有的节点,因为39放在这里就合法,那我把85放在这里也是合法的,因此当我把85转移到上面的时候,整颗子树就变得合法了,每次向上转移,他都会让一颗小子树合法,继续向上转移,又会让一颗小子树合法,此时我们发现85比99小,左边的子树就合法了,右边的子树本身就是合法的,因为85到来的时候并不会影响右子树,85向上调整的时候,他会让一个小子树再让一颗小子树变得合法,因此整个指数就变得合法了,所以这里为什么合法,就是一个简单比大小的过程,一直让大的元素向上再向上,上到不能再上的时候整个数就合法了,这就是堆的第一个核心操作向上调整算法,如果是小堆的话,就让小元素向上走

向上调整算法时间复杂度

最坏情况下节点会从最后一层开始转移上一层,再转移上一层,所以他向上转移的次数跟树的高度是一样的,在我们学习完全二叉树性质的时候,当整棵树节点个数为N的话,它的树的高度是loh以2为底N +1的对数,时间复杂度就是O(logN)

代码实现:

cpp 复制代码
const int N = 1e6 + 10;

int n;
int heap[N];

//向上调整算法
void up(int child) //每次和父亲做比较
{
	int parent = child / 2;
	//父节点存在且当前结点值大于父节点的权值
	while (parent >= 1 && heap[child] > heap[parent])
	{
		swap(heap[child], heap[parent]);
		child = parent;
		parent = child / 2;
	}
}
  • 这个向上调整算法是为建堆服务的,对我们建完堆之后再来测试
相关推荐
会员源码网2 小时前
使用`mysql_*`废弃函数(PHP7+完全移除,导致代码无法运行)
后端·算法
木心月转码ing3 小时前
Hot100-Day10-T438T438找到字符串中所有字母异位词
算法
HelloReader4 小时前
Wi-Fi CSI 感知技术用无线信号“看见“室内的人
算法
颜酱6 小时前
二叉树分解问题思路解题模式
javascript·后端·算法
qianpeng8978 小时前
水声匹配场定位原理及实验
算法
董董灿是个攻城狮19 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
blasit1 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
AI软著研究员1 天前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱1 天前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法