voidsiftUp(int[] heap, int i) { while (i > 0) { intparent= (i - 1) / 2; if (heap[parent] >= heap[i]) break; // 大顶堆 swap(heap, i, parent); i = parent; } }
时间复杂度:( O(\log n) )
2.2 下沉(Sift Down)
堆顶元素移除后,末尾元素放堆顶,与子节点比较交换。
voidsiftDown(int[] heap, int n, int i) { while (true) { intlargest= i; intleft=2 * i + 1; intright=2 * i + 2; if (left < n && heap[left] > heap[largest]) largest = left; if (right < n && heap[right] > heap[largest]) largest = right; if (largest == i) break; swap(heap, i, largest); i = largest; } }
时间复杂度:( O(\log n) )
2.3 建堆(Heapify)
从最后一个非叶子节点开始下沉:
voidbuildHeap(int[] arr) { intn= arr.length; for (inti= n / 2 - 1; i >= 0; i--) { siftDown(arr, n, i); } }
时间复杂度:( O(n) )(不是 ( O(n \log n) ))
证明:高度为 ( h ) 的节点最多有 ( \lceil n / 2^{h+1} \rceil ) 个,每个下沉 ( O(h) )。 [ \sum_{h=0}^{\log n} \frac{n}{2^{h+1}} \cdot h = O(n) ]
三、堆排序
voidheapSort(int[] arr) { buildHeap(arr); // 建大顶堆 for (inti= arr.length - 1; i > 0; i--) { swap(arr, 0, i); // 堆顶放末尾 siftDown(arr, i, 0); // 剩余元素重新堆化 } }
时间复杂度:( O(n \log n) ) 空间复杂度:( O(1) )
四、优先队列
4.1 接口定义
interfacePriorityQueue<T> { voidoffer(T element); // 入队 O(log n) T poll(); // 出队(优先级最高)O(log n) T peek(); // 查看队首 O(1) }