我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。
思路
以小堆为例,向下调整的实质就是将根节点与比它小的节点交换,逐渐下移,直到其子节点不再比它小为止。由此我们可以进行以下操作:
1、将根节点设为cur
2、进入循环,利用2 * cur + 1 找到左孩子,比较左孩子和右孩子的值,取其中较小的一个child
3、cur与这个child进行比较。若cur > child,则交换两数,并且将cur的位置更新为child,child的位置更新为2 * cur + 1;若cur <= child,则结束循环。注意,当child的位置越界时,也会结束循环。
代码实现
void shiftDown(int* arr, int n, int cur){
int child = 2 * cur + 1;
while (child < n){
if (child + 1 < n && arr[child] > arr[child + 1]){
child++;
}
if (arr[child] < arr[cur]){
int tmp = arr[cur];
arr[cur] = arr[child];
arr[child] = tmp;
cur = child;
child = 2 * cur + 1;
}
else{
break;
}
}
}
void test(){
int arr[] = { 10, 5, 3, 8, 7, 6 };
shiftDown(arr, sizeof(arr) / sizeof(arr[0]), 0);
}
void main(){
test();
return 0;
}