publicPQ(int n, Comparator<T> comparator) { this(n); this.comparator = comparator; }
publicbooleanisEmpty() { return n == 0; }
publicintsize() { return n; }
publicvoidinsert(T t) { arr[++n] = t; swim(n); }
public T removeTop() { exch(1, n); Ttemp= arr[n]; arr[n--] = null; sink(1); return temp; }
@Override public String toString() { StringBuilderres=newStringBuilder(); res.append("PQ["); for (inti=1; i <= n; i++) res.append(arr[i] + (i == n ? "" : ", ")); res.append("] size=" + (arr.length - 1)); return res.toString(); }
privatevoidswim(int k) { // 这里的 k 给的是数组的下标 while (k > 1 && stronger(k, k / 2)) { // 当 k 还没到根节点,且 k 比它的父节点“强” exch(k, k / 2); k = k / 2; } }
privatevoidsink(int k) { while (k * 2 <= n) { // 如果他还有下级的话 w // 这里找出 k 的两个子节点中更“强”的哪一个 inti= k * 2; if (i + 1 <= n && stronger(i + 1, i)) i++; if (!stronger(i, k)) return; // 如果 i 不比 k 强 exch(i, k); k = i; } }
privatevoidexch(int i, int j) { Ttemp= arr[i]; arr[i] = arr[j]; arr[j] = temp; }
privatebooleanstronger(int i, int j) { return comparator.compare(arr[i], arr[j]) < 0; } }
找到数组前 k 小的元素
对于 这一题,要找到数组的前 k 小的元素,则需要维护一个大小为 k 的大顶堆,其中元素代表当前找到的 k 个最小元素,然后遍历数组,如果找到的数小于大顶堆中最大的数,则更新堆,否则不做动作。这里只需要更改一下 insert 方法。
1 2 3 4 5 6 7 8 9 10
voidinsert(int i) { // 将 i 插入到堆中 if (!isFull()) { // 如果堆未满 arr[++p] = i; swim(p); } elseif (i < arr[1]) { arr[1] = i; sink(1); } }