1.向上调整算法
核心逻辑:新插入的数据和其的父节点进行比较,根据大小堆的性质来进行比较,然后根据比较情况决定是否交换。
补充知识点,如下图:
代码实现:
void AdjustUp(HPDataType* array, int child)//向上调整算法
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (array[child] < array[parent])//小堆
{
Swap(&array[child], &array[parent]);
child = parent;
parent = (parent - 1) / 2;
}
else
{
break;
}
}
}
大堆的向上调整只需改变while语句后的符号即可。
2.需要向下调整算法的场景之一就是进行堆排序时,Pop数据后进行维持堆结构时,代码场景如下:
void HPPop(HP* php)
{
assert(php);
assert(php->size > 0);
Swap(&php->array[0], &php->array[php->size - 1]);//交换第一个和最后一个数据。
php->size--;
AdjustDown(php->array,php->size,0);//交换后要保持堆结构,进行向下调整。
}
AdjustDown函数实现:
void AdjustDown(HPDataType* arr, int size, int parent)
{
int child = (parent * 2) + 1;
while (child < size)
{
//使用假设法
if (child + 1 < size && arr[child + 1] < arr[child])//得到较小值的下标
{
++child;
}
if (arr[parent] > arr[child])
{
Swap(&arr[parent], &arr[child]);
parent = child;
child = (parent * 2) - 1;
}
else
{
break;
}
}
}
向上/向下调整算法是堆排序的核心算法,判断是否成功,可以进行测试
main函数代码:
int main()
{
HP d1;
HPInit(&d1);
int arr[] = { 60,70,65,50,32,100 };
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
{
HPPush(&d1, arr[i]);
}
//printf("%d\n", HPSize(&d1));
while (!HPEmpty(&d1))
{
printf("%d ", HPTop(&d1));
HPPop(&d1);
}
return 0;
}
结果: