Java中实现大/小根堆

本文介绍了堆数据结构的概念,包括小根堆和大根堆,并详细阐述了如何用数组存储堆。堆的主要操作——插入和删除,通过向下调整和向上调整算法实现,时间复杂度均为O(logn)。此外,还展示了如何构建和调整堆的过程,总结了堆操作的简洁性。
摘要由CSDN通过智能技术生成

用一道算法题来说明堆的使用场景
leetecode-215

堆的介绍

小根堆:父节点的值小于或等于子节点的值
大根堆:父节点的值大于或等于子节点的值
在这里插入图片描述

堆的存储

这个是特别值得一说的,因为跟后面的实现相关。一般都是用数组来存储的,Java中的优先队列就是用Object[]数组存储;尽管堆是一个完全二叉树,但一般不用树结构来存储,正因为是完全二叉树,有非常多特殊的性质,正好可以用数组来存储。
这里最关键的性质是:

1)i结点的父结点下标就为(i–1)/2;
2)i节点左右子结点下标分别为2 * i + 1和2 * i + 2
在这里插入图片描述

堆的操作

插入:插入在堆尾,然后从下往上进行调整;调整一遍即可变有序,时间复杂度为o(logn)

private static void siftUp(int[] heap, int i) {
    if (i <= 0) return;
    // 父节点
    int parent = (i - 1) / 2;
    if (heap[parent] > heap[i]) {
        int t = heap[i];
        heap[i] = heap[parent];
        heap[parent] = t;
        siftUp(heap, parent); // 递归往上
    }
}

删除:一般是弹出堆顶元素,然后用末尾元素替换堆顶元素,然后进行向下调整。时间复杂度也为o(logn)

    private static void siftDown(int[] heap, int i) {
        // 写一个递归的方式
        int left = i * 2 + 1;
        int right = i * 2 + 2;
        int minIndex = getMinIndex(heap, i, left, right);
        if (minIndex != i) {
            int tem = heap[i];
            heap[i] = heap[minIndex];
            heap[minIndex] = tem;
            // 递归调整子节点
            siftDown(heap, minIndex);
        }
    }
    private static int getMinIndex(int[] heap, int i, int left, int right) {
        int minIndex = i;
        if (left < size && heap[left] < heap[i]) {
            minIndex = left;
        }
        if (right < size && heap[right] < heap[minIndex]) {
            minIndex = right;
        }
        return minIndex;
    }
堆的实现

调整堆/构造堆
从i = n/2 - 1节点开始调整,这之后的都是叶节点

    private static void heapIfy(int[] heap) {
        // 最后一个非叶子节点开始调整
        int i = size / 2 - 1;
        for (; i >= 0; i--) {
            siftDown(heap, i);
        }
    }

总结

堆这种结构看似很吓人,感觉很难得样子。但真正理解了会发现很好实现得,它本质上就只有两种操作:
1)向下调整
2)向上调整
另外,这两种操作还有非递归实现方式,有兴趣得可以思考并实现一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值