1.堆中插入数据
堆插入数据我们是从尾部插入,插入数据不应该改变堆的性质(即不改变堆之前大堆或小堆的性质),比如在小堆时,如果插入的数据比插入位置的父结点小就不需要进行额外操作,但是如果插入的数据比插入位置的父结点大就需要进行相应调整,让其依然是小堆。
比如上图的堆要插入的数据是13,应该如何进行调整?
我们可以发现插入的数据只是对一条路上的数据有影响,我们只需要调整这一条路的数据即可。
调整的方法我们使用向上调整算法
1.通过插入位置坐标得到插入结点(我这里还是叫child)的父亲结点;
2.比较插入结点(child)和父亲结点,如果父亲结点大于插入的结点,将他们互换,反之跳出while
3.互换之后将当前原父亲结点的坐标赋值给child,再求出当前child的父亲结点,继续步骤2.
4.直到child=0循环结束
(插入之前还是老规矩,看看空间是否满了,满了需要扩容)
//向上调整
void AdjustUp(HPDataType* a, int n, int child)
{
int 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 HeapPush(Heap* php, HPDataType x)
{
assert(php);
if (php->_capacity == php->_size)
{
php->_capacity *= 2;
HPDataType* tmp = (HPDataType*)realloc(php->_a, sizeof(HPDataType) * php->_capacity);
if (tmp == NULL) // 检查内存分配是否成功
{
printf("realloc failed\n");
return;
}
php->_a = tmp;
}
php->_a[php->_size++] = x;
AdjustUp(php->_a, php->_size, php->_size - 1);
}
2. 删除堆顶数据
1.将堆顶的数据和数组的最后一个数据互换;
2.再进行向下调整
向下调整算法可以参考这篇博客:
//删除堆顶数据
void HeapPop(Heap* php)
{
assert(php);
assert(php->_size > 0);
swap(&php->_a[0], &php->_a[php->_size - 1]);
php->_size--;
AdjustDown(php->_a, php->_size, 0);
}
相关文章:
【数据结构】树的概念及结构-CSDN博客