zoukankan      html  css  js  c++  java
  • 优先级队列Priority_queue

    定义

    拥有权值观点的queue,,一个是返回最高优先级对象,一个是在底端添加新的对象。这种数据结构就是优先级队列(Priority Queue) 。

    实现

    利用max_heap完成,以vector表现的完全二叉堆。max_heap可以满足priority_heap所需要的依照权值高低自动递减的特性。

    二叉堆

    二叉堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 有了这一性质,那么二叉堆上最大值就是根节点了。

    二叉堆的表现形式:我们可以使用数组的索引来表示元素在二叉堆中的位置。

    Heap representation

    从二叉堆中,我们可以得出:

    · 元素k的父节点所在的位置为[k/2]

    · 元素k的子节点所在的位置为2k和2k+1

    跟据以上规则,我们可以使用二维数组的索引来表示二叉堆。通过二叉堆,我们可以实现插入和删除最大值都达到O(nlogn)的时间复杂度。

    对于堆来说,最大元素已经位于根节点,那么删除操作就是移除并返回根节点元素,这时候二叉堆就需要重新排列;当插入新的元素的时候,也需要重新排列二叉堆以满足二叉堆的定义。现在就来看这两种操作。

    从下至上的重新建堆操作: 如果一个节点的值大于其父节点的值,那么该节点就需要上移,一直到满足该节点大于其两个子节点,而小于其根节点为止,从而达到使整个堆实现二叉堆的要求。

    Swim operation in Priority queue

    由上图可以看到,我们只需要将该元素k和其父元素k/2进行比较,如果比父元素大,则交换,然后迭代,一直到比父元素小为止。

    private static void Swim(int k)
    {
        //如果元素比其父元素大,则交换
        while (k > 1 && pq[k].CompareTo(pq[k / 2]) > 0)
        {
            Swap(pq, k, k / 2);
            k = k / 2;
        }
    }

    这样,往堆中插入新元素的操作变成了,将该元素从下往上重新建堆操作:

    Insert item into the binary heap

    代码实现如下:

    public static void Insert(T s)
    {
        //将元素添加到数组末尾
        pq[++N] = s;
        //然后让该元素从下至上重建堆
        Swim(N);
    }

    动画如下:

    inset item into the binary heap

    由上至下的重新建堆操作:当某一节点比其子节点要小的时候,就违反了二叉堆的定义,需要和其子节点进行交换以重新建堆,直到该节点都大于其子节点为止:

    Sink operation in Priority queue

    代码实现如下:

    private static void Sink(int k)
    {
        while (2 * k < N)
        {
            int j = 2 * k;
            //去左右子节点中,稍大的那个元素做比较
            if (pq[j].CompareTo(pq[j + 1]) < 0) j++;
            //如果父节点比这个较大的元素还大,表示满足要求,退出
            if (pq[k].CompareTo(pq[j]) > 0) break;
            //否则,与子节点进行交换
            Swap(pq, k, j);
            k = j;
        }
    }

    这样,移除并返回最大元素操作DelMax可以变为:

    1. 移除二叉堆根节点元素,并返回

    2. 将数组中最后一个元素放到根节点位置

    3. 然后对新的根节点元素进行Sink操作,直到满足二叉堆要求。

    移除最大值并返回的操作如下图所示:

    Delete the max item in binary heap

    以上操作的实现如下:

    public static T DelMax()
    {
        //根元素从1开始,0不存放值
        T max = pq[1];
        //将最后一个元素和根节点元素进行交换
        Swap(pq, 1, N--);
        //对根节点从上至下重新建堆
        Sink(1);
        //将最后一个元素置为空
        pq[N + 1] = default(T);
        return max;
    }

    动画如下:

    del max in the binary heap

  • 相关阅读:
    vue--vuex详解
    vue2.0的一个小demo,
    vue---子调父 $emit (把子组件的数据传给父组件)
    高阶函数总结
    三个方法(apply、call、bind)
    JS的一些总结(函数声明和函数表达式的区别,函数中的this指向的问题,函数不同的调用方式,函数也是对象,数组中的函数调用)
    原型对象(下)
    案例:贪吃蛇
    原型对象(上)
    案例(拖拽对话框、高清放大镜、自制滚动条、元素的隐藏方式、表格隔行变色、tab切换效果、字符串拼接、刷新评论)
  • 原文地址:https://www.cnblogs.com/LUO77/p/5825169.html
Copyright © 2011-2022 走看看