2020-04-01 08:15:56
问题描述:
给出一个整数数组,堆化操作就是把它变成一个最小堆数组。
对于堆数组A,A[0]是堆的根,并对于每个A[i],A [i * 2 + 1]是A[i]的左儿子并且A[i * 2 + 2]是A[i]的右儿子。
样例
输入 : [3,2,1,4,5] 输出 : [1,2,3,4,5] 解释 : 返回任何一个合法的堆数组
挑战
O(n)的时间复杂度完成堆化
问题求解:
由于堆有一个性质就是其是完全二叉树,那么我们就可以从非叶子节点开始向下过滤,具体的操作就是从上往下将最小的置为根。
通过对每次过滤的节点数的估算,即n / 2 + n / 4 + ... + 1 = n。
时间复杂度:O(n)
public void heapify(int[] A) { for (int i = A.length / 2; i >= 0; i--) { siftdown(A, i); } } private void siftdown(int[] A, int idx) { if (idx >= A.length) return; int k = idx; if (idx * 2 + 1 < A.length && A[idx * 2 + 1] < A[k]) k = idx * 2 + 1; if (idx * 2 + 2 < A.length && A[idx * 2 + 2] < A[k]) k = idx * 2 + 2; if (k == idx) return; int temp = A[idx]; A[idx] = A[k]; A[k] = temp; siftdown(A, k); }