ToB企服应用市场:ToB评测及商务社交产业平台
标题:
数据布局:堆
[打印本页]
作者:
风雨同行
时间:
2024-12-29 19:21
标题:
数据布局:堆
目录
1.堆的概念
2.堆的布局
3.堆的初始化
4.堆的烧毁
5.堆的插入
6.堆的删除
7.判断堆是否为空
1.堆的概念
堆的性子:
堆中某个结点的值总是不大于或不小于其父结点的值;
堆总是一棵完全二叉树。
以下堆的布局默认大堆 :
2.堆的布局
堆是非线性数据布局,相当于一维数组,有两个直接后继 。
//大堆
typedef int HPDataType;
typedef struct Heap
{
HPDataType* _a;
int _size; //数组中元素的个数
int _capacity; //数组的容量
}Heap;
复制代码
堆是怎样存储在数组中呢?
在数组下标中,若
当前节点
在
数组
中的
下标
为
i
, 则其
父节点
的
下标
为
(i-1)/2
,其
左子节点
的下标为
i*2+1
,其右子节点的下标为
i*2+1+1
;
若一个节点的下标为3,其父节点的小标为1,其左孩子节点的下标为7,右孩子结点的下标为8。
3.堆的初始化
/初始化
void HeapInit(Heap* php)
{
assert(php);
php->_a = (HPDataType*)malloc(sizeof(HPDataType)*5);
php->_size = 0;
php->_capacity = 5;
}
复制代码
4.堆的烧毁
// 堆的销毁
void HeapDestory(Heap* php)
{
free(php->_a);
php->_size = 0;
php->_capacity = 0;
}
复制代码
5.堆的插入
首先插入时,判断数组空间是否已满,若满了则扩容,接着在数组的最后举行插入,然后举行向上调整(向上调整就是判断父亲和孩子的大小,若孩子大于父亲则举行交换,)
void Swap(HPDataType* p1, HPDataType* p2)
{
HPDataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void AdjustUp(Heap* php, int child)
{
assert(php);
// 找到插入节点的父结点的下标
int parent = (child - 1) / 2;
while (child > 0)
{
// 若孩子结点大于父亲结点,则父亲和孩子进行交换,然后改变父亲结点和孩子结点的下标
if (php->_a[child] > php->_a[parent])
{
Swap(&php->_a[child], &php->_a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
// 堆的插入
void HeapPush(Heap* php, HPDataType x)
{
assert(php);
//扩容
if (php->_size == php->_capacity)
{
HPDataType* tmp = (HPDataType*)realloc(php->_a, sizeof(HPDataType) * php->_capacity * 2);
if (tmp == NULL)
{
perror("push::realloc");
return;
}
php->_a = tmp;
php->_capacity *= 2;
}
php->_a[php->_size] = x;
php->_size++;
//向上调整
// 插入元素的数组下标
AdjustUp(php, php->_size - 1);
}
复制代码
6.堆的删除
这里的删除是删除数组中第一个元素(即最大的的元素),首先将数组中最后一个元素和第一个元素举行交换,然后举行向下调整,满足大堆的条件
void AdjustDown(Heap* php,int n,int parent)
{
assert(php);
//找到左孩子
int child = parent * 2 + 1;
while (child < n)
{
//判断右孩子是否存在, 若存在则将左孩子和右孩子进行比较
// 若右孩子大于左孩子,则将右孩子与父亲作比较,即child++,找到右孩子下标
if (child + 1 < n && php->_a[child] < php->_a[child + 1])
{
child++;
}
//当父母小于孩子时,交换,同时重新赋值父亲结点和孩子结点
if(php->_a[parent] < php->_a[child])
{
Swap(&php->_a[parent], &php->_a[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
// 堆的删除
void HeapPop(Heap* php)
{
assert(php);
assert(!HeapEmpty(php));
//删除头元素
Swap(&php->_a[0], &php->_a[php->_size - 1]);
php->_size--;
//向下调整
// 需要从根节点进行调整
AdjustDown(php,php->_size,0);
}
复制代码
7.判断堆是否为空
// 堆的判空 空1,非空0
int HeapEmpty(Heap* php)
{
assert(php);
return php->_size == 0;
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4