算法:向上/向下调整算法

一、引言

在堆中,我们常常需要用到两个算法:向上调整算法和向下调整算法。

对于堆的“增” “删”而言,需要将堆保持原来的大小堆序,需要对数据修调整后,对堆进行调整。

此时 增,需要用到向上调整算法; 删, 需要用到向下调整算法。

目录

一、引言

二、算法介绍

1.向上调整算法:

条件:

公式:

实现:

2.向下调整算法:

前提:

执行:

代码:

三、算法复杂度


二、算法介绍

1.向上调整算法:

条件:

保证其余数据满足堆
顺着宗族线往上走
已知孩子,找父亲。

公式:

leftchild = parent * 2 +1

rightchild = parent * 2 +2

parent = (child - 1) / 2

实现:



//前提:再调整之前,已经是一个大、小堆

void AdjustUp(HPDataType* a, int child)		//通过  调整  向上算法,可以实现 大小堆 的转换。
{
	int parent = (child - 1) / 2;
	//while (parent >= 0)
	while(child > 0)
	{
		if (a[child] > a[parent])			
		{
			Swap(&a[child], &a[parent]);

			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}

需要注意的是,需要通过child = parent; parent = (child - 1 ) / 2;这两个语句,保证数组遍历不断往下进行。

2.向下调整算法:

前提:

在调整之前,左、右子树(除根的部分)是大、小堆。

执行:

建立大堆:找大孩子;建立小堆,找小孩子。

代码:


void AdjustDown(int* a, int n, int parent)		//下调从parent开始。上调从child开始
{
	int child = parent * 2 + 1;		//默认左孩子小。	左孩子存在,不一定有右孩子,左孩子不存在,一定没有右孩子
	while (child < n)		//孩子不存在(n是大小,不是下标)
	{
		// 选出左右孩子中小/大的那个
		if (child + 1 < n			//child + 1 < n  如果 有孩子存在(下标符合规范)  判断语句必须写在之前!否则默认child + 1 合法([ ] 会检查越界)	
			&& a[child+1] > a[child])		//child + 1 是右孩子的下标
		{
			++child;
		}

		if (a[child] > a[parent])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;		//默认左孩子	
		}
		else
		{
			break;
		}
	}
}

需要注意的是,使用下标,必须要进行下标范围的检查,防止越界。

三、算法复杂度

时间复杂度为O(logN)

原因:最多需要遍历的次数为树的高度。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值