二叉树实现堆

1. 堆的定义

2. 如何利用二叉树实现堆

堆的定义:如果有一个关键码的集合K = { , , ,…, },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足: <= 且 <= ( >= 且 >= ) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

性质

  • 堆中某个节点的值总是不大于或不小于其父节点的值
  • 堆总是一棵完全二叉树。

小堆如图如下

跟小小堆

大堆如图如下

根为最大叫大堆

堆的实现:

这个视频模拟了插入中小堆的实现,如何移动的过程。

小堆

定义结构体


typedef int HPDatatype;
typedef struct Heap
{
	HPDatatype* a;
	size_t size;
	size_t capacity;

}Hp;

```c
//堆排序代码
void AdjustUp(HPDatatype* a, size_t child)
{
	//小的在上的排序法
	size_t parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]); 
				child = parent;
			parent = (child - 1) / 2;
		}

		else
		{
			break;

		}
	}

	
}
//堆内元素交换代码
void Swap(HPDatatype* pa, HPDatatype* phh)
{
	HPDatatype tmp = *pa;
	*pa = *phh;
	*phh = tmp;

}

以上是实现过程中自己实现的排序和交换代码。分开更容易理解。

函数名
初始化堆void HeapInit(Hp* hpp)
堆的销毁void HeapDestroy(Hp* hpp)
堆的插入void HeapPush(Hp* hpp, HPDatatype x)
堆的打印void HeapPrint(Hp* hpp)
堆的删除void HeapPop(Hp* hpp)
堆的判空bool HeapEmpty(Hp* phh)
堆的深度size_t HeapSize(Hp* phh)

**1.**堆的初始化:
我们将创建的结构体里面的数组置为空处理。在将容量和长度初始化为0。
下面展示一些 内联代码片

void HeapInit(Hp* hpp)
{
	assert(hpp);
	hpp->a = NULL;
	hpp->size = hpp->capacity = 0;

}
**2.**对我们的堆进行销毁:
我们释放数组里面的数据。在将a置为空,在将容量和长度初始化为0。这步和初始化一样。

```c
void HeapDestroy(Hp* hpp)
{
	assert(hpp);
	free(hpp->a);
	hpp->a = NULL;
	hpp->size = hpp->capacity = 0;


}

3.堆的插入:
这步比较特殊里面有内存开辟先判断空间是否存在,如果不存在就开辟空间。开辟完后将值放入结构体数组里面,我们创建个函数进行堆排序**函数名为void AdjustUp(HPDatatype* a, size_t child)**在这个函数里面又有Swap函数是一个交换函数具体使用就是将头和尾进行交换代码如下:

在这里插入图片描述




//插入
void HeapPush(Hp* hpp, HPDatatype x)
{
	assert(hpp);
	if (hpp->size == hpp->capacity)
	{
		size_t newCapacity = hpp->capacity == 0 ? 4 : hpp->capacity * 2;
		HPDatatype* tmp = realloc(hpp->a,sizeof(HPDatatype)* newCapacity);
		if (tmp == NULL)
		{
			printf("realloc failed\n");
			exit(-1);

		}
		hpp->a = tmp;
		hpp->capacity = newCapacity;
	}
	hpp->a[hpp->size] = x;
	++hpp->size;
	//大/小堆排序
	AdjustUp(hpp->a, hpp->size-1);
}

**4.**堆的删除:
我们对堆进行断言,使堆中有数据存在。
我们将堆首和堆尾元素进行交换,在使size–这样就将我们删除的元素给删除了。删除完在进行排序继续使用AdjustDown函数进行堆排序

void HeapPop(Hp* hpp)
{
	assert(hpp);
	assert(hpp->size > 0);
	Swap(&hpp->a[0], &hpp->a[hpp->size-1]);
	--hpp->size;
	AdjustDowm(hpp->a, hpp->size, 0);
}

**5.**堆的判空:
这边使用的是c++里面bool,如有需要自己查。

bool HeapEmpty(Hp* hpp)
{
	assert(hpp);

	return hpp->size == 0;
}

**6.**堆的深度:
直接将结构体中size取出即为深度。

size_t HeapSize(Hp* hpp)
{
	assert(hpp);

	return hpp->size;
}

总结:

学习使我强大。我要变强在这里插入图片描述

  • 33
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 27
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华华的bit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值