其他分享
首页 > 其他分享> > 堆结构-高效维护数据集中最大最小值问题

堆结构-高效维护数据集中最大最小值问题

作者:互联网

堆结构介绍

堆结构是一颗完全二叉树,堆结构可以实现O(log n)级别的插入数据的时间复杂度,查询最大最小值可以达到O(1)的效率。

堆结构实现

堆结构维护代码

void put(int data){
    int ch,fa;//child,father
    heap[++heap_size]=data;//heap_size为全局变量 堆内元素个数
    ch = heap_size;//从堆尾开始查找
    while(ch>1){//child不为根
        fa = ch / 2;//父亲位置
        if(heap[ch] <= heap[fa])break;//如果child不够大,就没必要冒上去
        swap(heap[ch],heap[fa]);//否则交换二值
        ch = fa;//更新
    }
}

堆结构实现

Java定义堆结构

    PriorityQueue<Integer> min = new PriorityQueue<>(); // 小顶堆
    PriorityQueue<Integer> max = new PriorityQueue<>((x, y) -> (y - x)); // 大顶堆

堆结构使用

  1. 295. 数据流的中位数
    题目:
    这道题要实现一个数据结构,用来保存一个数据流,支持向数据流中插入数据和查询数据流中的中位数,操作数量是50000次。
    分析
    如果是插入之后排序,假设插入和查询是1:1,那么每次排序的复杂度是n*log n ,就是25000 * 16 * 25000 ,时间复杂度过高。
    如果我们把这段数据流分为两段,一段保存排序后的左半部分,一半保存排序后的右半部分,例如 1,2 ; 3,4 ,这个数据流的中位数就是 (2 + 3)/2。
    对于左半部分只需要知道左半部分的最大值,右半部分只需要知道最小值,则可以使用堆结构来维护最大最小即可。
    维护方法
class MedianFinder {
    Queue<Integer> A, B;
    public MedianFinder() {
        A = new PriorityQueue<>(); // 小顶堆,保存较大的一半
        B = new PriorityQueue<>((x, y) -> (y - x)); // 大顶堆,保存较小的一半
    }
    public void addNum(int num) {
        if(A.size() != B.size()) {
            A.add(num);
            B.add(A.poll());
        } else {
            B.add(num);
            A.add(B.poll());
        }
    }
    public double findMedian() {
        return A.size() != B.size() ? A.peek() : (A.peek() + B.peek()) / 2.0;
    }
}

标签:大顶,高效,PriorityQueue,最小值,数据流,小顶,维护,数据,size
来源: https://www.cnblogs.com/xyqxyq/p/16139430.html