Java 实现大根堆

Java 实现大根堆

1. 大根堆

堆是一种比较常见的数据结构,在 Java 里有 PriorityQueue 就是堆的一种实现,自己代码实现堆结构有助于更好地理解这种数据结构,以便于我们能够更好地去运用它。

class MaxHeap {
    int[] maxHeap;
    int capacity; // 堆的容量
    int size; // 堆实际大小

    public MaxHeap(int n) {
        maxHeap = new int[n];
        capacity = n;
        size = 0;
    }
    // 交换堆中 p q 下标对应的元素
    private void swap(int p, int q) {
        int tmp = maxHeap[p];
        maxHeap[p] = maxHeap[q];
        maxHeap[q] = tmp;
    }

    public void offer(int element) {
        // 堆的大小已经到达了最大容量,不能再继续添加
        if (isFull() == true) {
            System.out.println("The MaxHeap is FULL!");
            return;
        }
        maxHeap[size++] = element;
        // 从添加处开始向上调整堆结构
        int idxStart = size - 1;
        int idxFather = (idxStart - 1) >> 1;
        while (idxFather >= 0 && maxHeap[idxStart] > maxHeap[idxFather]) {
            swap(idxStart, idxFather);
            idxStart = idxFather;
            idxFather = (idxStart - 1) >> 1;
        }
    }

    public int peek() {
        return maxHeap[0];
    }

    public int poll() {
        // 堆为空,不能再弹出元素
        if (isEmpty() == true) {
            System.out.println("The MaxHeap is EMPTY!");
            return -1;
        }
        int popVal = maxHeap[0];
        maxHeap[0] = maxHeap[--size]; // 将堆中最后一个元素放置到堆顶
        // 开始向下调整堆(因为上一步是将最后一个元素放置到堆顶,可能打破了大根堆的结构)
        int idxStart = 0;
        int idxLeft = (idxStart << 1) + 1, idxRight = idxLeft + 1;
        int largest = 0;
        while (idxLeft < size) {
            // 找左右孩子中较大的那个,用 largest 记录其下标
            if (idxRight < size && maxHeap[idxRight] > maxHeap[idxLeft]) {
                largest = idxRight;
            } else {
                largest = idxLeft;
            }
            // 如果当前元素比左右孩子中较大的那个还大,说明依旧保持大根堆结构,不用再继续
            if (maxHeap[idxStart] > maxHeap[largest]) {
                break;
            }

            // 否则,将左右孩子中较大的那个替换到其父亲的位置,然后继续向下调整
            swap(idxStart, largest);
            idxStart = largest;
            idxLeft = (idxStart << 1) + 1;
            idxRight = idxLeft + 1;
        }
        return popVal;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public boolean isFull() {
        return size == capacity;
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值