二叉树1建堆调整

本文详细介绍了二叉树在数组存储形式下如何通过堆实现最值问题的解决,特别是针对小堆和大堆的向下调整过程。通过shiftDown函数展示了如何在删除操作中保持堆的性质。同时,给出了建堆的过程,从最后一个非叶子节点开始向下调整,确保整个结构满足堆的特性。此外,还提供了两个测试用例以验证调整和建堆的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树的调整,建堆
//二叉树
//使用数组顺序存储二叉树
//二叉树的另一种存放形式就是使用堆来实现
//堆一般用来求解的是最值问题。堆分为大堆小堆两种情况,这里涉及二叉树的删除的操作
//其实就是堆的情况就是会使用的是数组来进行存放,依次由小到大。
//向下调整,调整就是要保证子结构是堆,再就是表示的是如果现在不是的话就得进行遍历。
//向下调整:
//1.从左右孩子中选择一个最小值
//2.当前需要调整的数据和最小值进行比较
//大于最小值:和最小值进行交换,从调整的位置继续执行第一步
//小于等于最小值;结束调整。

//假设为小堆
void shiftDown(int* arr, int n, int curPos)
{
//左孩子
int child = 2 * curPos + 1;
while (child < n)
{
//从左右孩子中找到一个最小值的位置
if (child+1<n && arr[child + 1] < arr[child])
++child;
//需要调整的数据和最小值进行比较
if (arr[child] < arr[curPos])
{
int tmp = arr[child];
arr[child] = arr[curPos];
arr[curPos] = tmp;

			//更新位置
			curPos = child;
			child = 2 * curPos + 1;
		}
	   else
		   break;
}

}

//假设为大堆(子结构是大堆)现在也是一个向下调整的过程
void shiftDown(int* arr, int n, int curPos)
{
//左孩子
int child = 2 * curPos + 1;
while (child < n)
{
//从左右孩子中找到一个最大值的位置
if (child + 1 < n && arr[child + 1]> arr[child])
++child;
//需要调整的数据和最大值进行比较
if (arr[child] > arr[curPos])
{
int tmp = arr[child];
arr[child] = arr[curPos];
arr[curPos] = tmp;

		//更新位置
		curPos = child;
		child = 2 * curPos + 1;
	}
	else
		break;
}

}

void test1()
{
int arr[] = { 10,5,3,8,7,6 };
shiftDown(arr, sizeof(arr) / sizeof(arr[0]), 0);
}

void test2()
{
int arr[] = { 7,56,30,25,15,10 };
shiftDown(arr, sizeof(arr) / sizeof(arr[0]), 0);
}
int main()
{
test1();
test2();
test();
return 0;
}

//建堆
//小堆–>大堆
//调整的过程 首先是确定的是确保左右子结构是堆才是可以进行继续操作
//调整的就是最后一个非叶子结点开始进行向下调整。
//向下调整的次数是和非叶子结点个数是相同的。
//最后一个非叶子结点的位置(索引);
//(n-2)/2

void creatHeap(int* arr, int n)
{
//从最后一个非叶子开始向下调整
for (int i = (n - 2) / 2; i >= 0; --i)
{
//shiftDown(数组指针,数组元素个数,调整的起始位置)
shiftDown(arr, n, i);
}
}

void test()
{
int arr[] = { 100,20,3,6,89,12,15,36,25 };
creatHeap(arr, sizeof(arr) / sizeof(arr[0]));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值