最小堆JAVA(Top K问题)

Top k问题很多情况下比较常用的解决方法就是最小堆,最小堆的建立一般基于数组来模仿树的结构,左右子树和父节点都可以根据数学关系式来呈现,代码如下:

public class MinHeap
{
    // 堆的存储结构 - 数组
    private int[] data;

    // 将一个数组传入构造方法,并转换成一个小根堆
    public MinHeap(int[] data)
    {
        this.data = data;
        buildHeap();
    }

    // 将数组转换成最小堆
    private void buildHeap()
    {
        // 完全二叉树只有数组下标小于或等于 (data.length) / 2 - 1 的元素有孩子结点,遍历这些结点。
        // *比如上面的图中,数组有10个元素, (data.length) / 2 - 1的值为4,a[4]有孩子结点,但a[5]没有*
        for (int i = (data.length) / 2 - 1; i >= 0; i--) 
        {
            // 对有孩子结点的元素heapify
            heapify(i);
        }
    }

    private void heapify(int i)
    {
        // 获取左右结点的数组下标
        int l = left(i);  
        int r = right(i);

        // 这是一个临时变量,表示 跟结点、左结点、右结点中最小的值的结点的下标
        int smallest = i;

        // 存在左结点,且左结点的值小于根结点的值
        if (l < data.length && data[l] < data[i])  
            smallest = l;  

        // 存在右结点,且右结点的值小于以上比较的较小值
        if (r < data.length && data[r] < data[smallest])  
            smallest = r;  

        // 左右结点的值都大于根节点,直接return,不做任何操作
        if (i == smallest)  
            return;  

        // 交换根节点和左右结点中最小的那个值,把根节点的值替换下去
        swap(i, smallest);

        // 由于替换后左右子树会被影响,所以要对受影响的子树再进行heapify
        heapify(smallest);
    }

    // 获取右结点的数组下标
    private int right(int i)
    {  
        return (i + 1) << 1;  
    }   

    // 获取左结点的数组下标
    private int left(int i) 
    {  
        return ((i + 1) << 1) - 1;  
    }

    // 交换元素位置
    private void swap(int i, int j) 
    {  
        int tmp = data[i];  
        data[i] = data[j];  
        data[j] = tmp;  
    }

    // 获取对中的最小的元素,根元素
    public int getRoot()
    {
            return data[0];
    }

    // 替换根元素,并重新heapify
    public void setRoot(int root)
    {
        data[0] = root;
        heapify(0);
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值