zoukankan      html  css  js  c++  java
  • 优先队列和二叉堆

    优先队列是一种常用的ADT,其中的元素有序排列,入队的元素会插入到正确的位置,队首元素始终为最小(大)值,队首出队后优先队列仍然保持原来的性质。

    这里我们规定优先队列以升序排列。

    优先队列提供的接口包括:

    • insert 插入元素
    • top 得到队首元素
    • pop 删除队首元素

    二叉堆是优先队列一种常用的实现,二叉堆是一种完全二叉树,完全二叉树除最低一层外其它层均被填满,最低一层的节点全部集中在左侧。完全二叉树的性质决定它可以很容易地由二叉数组来实现。

    二叉堆满足堆序性,即任意一个节点X的父节点不大于X(最小堆)。由堆序性可知,二叉堆的根节点一定为最小值或最大值,根节点为最小值的堆称为最小堆,根节点为最大值的堆称为最大堆。

    最小堆类的声明:

    template<typename val_t>
    class MinHeap {
    protected:
        const static size_t capcity = 10000;
        size_t size;
        val_t vec[capcity];
    public:
        MinHeap();
        void insert(val_t val);
        bool empty();
        void rmMin();
        val_t getMin() {
            return vec[1];
        };
        ~MinHeap() = default;
    };
    

    插入元素

    插入元素采用上滤的方法:

    (1)在数组超出末端(size位置)创建一个空穴

    (2)比较新元素与空穴父节点的大小,若新元素较大则将原父节点填入空穴,原父节点的位置变为空穴

    (3)直至新元素不大于空穴父节点时停止空穴上溯

    template<typename val_t>
    void MinHeap<val_t>::insert(val_t val) {
        size_t  i;
        for (i = ++size; vec[i/2] > val; i /= 2) { 
            vec[i]  =  vec[i / 2];
        }
        vec[i] =  val;
    }
    

    在实现过程中,我们只是用i标记了空穴的位置,并没有交换空穴与父节点的位置。

    删除根元素

    删除元素采用恰好相反的下滤策略:

    (1) 移除根节点后在根节点处产生了一个空穴

    (2) 比较空穴的左右子节点,较大的一个与空穴交换位置,直至空穴到达最下层

    (3) 将原来最后一个元素填入空穴的位置

    template<typename val_t>
    void MinHeap<val_t>::rmMin() {
        size_t  i, next;
        val_t min, last;
        if (empty()) {
            return;
        }
        min  = vec[1];
        last = vec[size--];
        for (i = 1; i * 2 <= size; i = next) {
            //find smaller next
            next = i * 2;
            if (next != size && vec[next + 1] < vec[next]) {
                next++;
            }
            //
            if (last > vec[next]) {
                vec[i] = vec[next];
            }
            else {
                break;
            }
        }
        vec[i] = last;
    }
    

    一言不发就丢代码:

    #include <iostream>
    //#include <vector>
    
    using namespace std;
    
    template<typename val_t>
    class MinHeap {
    protected:
        const static size_t capcity = 10000;
        size_t size;
        val_t vec[capcity];
    public:
        MinHeap();
        void insert(val_t val);
        bool empty();
        void rmMin();
        val_t getMin() {
            return vec[1];
        };
        ~MinHeap() = default;
    };
    
    template<typename val_t>
    MinHeap<val_t>::MinHeap() {
        size = 0;
    }
    
    template<typename val_t>
    bool MinHeap<val_t>::empty() {
        if (size) {
            return false;
        }
        else {
            return true;
        }
    }
    
    template<typename val_t>
    void MinHeap<val_t>::insert(val_t val) {
        size_t  i;
        for (i = ++size; vec[i/2] > val; i /= 2) { //covert > to <, to get a max heap
            vec[i]  =  vec[i / 2];
        }
        vec[i] =  val;
    }
    
    template<typename val_t>
    void MinHeap<val_t>::rmMin() {
        size_t  i, next;
        val_t min, last;
        if (empty()) {
            return;
        }
        min  = vec[1];
        last = vec[size--];
        for (i = 1; i * 2 <= size; i = next) {
            //find smaller next
            next = i * 2;
            if (next != size && vec[next + 1] < vec[next]) {
                next++;
            }
            //
            if (last > vec[next]) {
                vec[i] = vec[next];
            }
            else {
                break;
            }
        }
        vec[i] = last;
    }
  • 相关阅读:
    python3 连接HBase
    xgb 绘制
    手机UA识别
    meta常用标签总结
    window.requestAnimationFrame() ,做逐帧动画,你值得拥有
    三年从前端小工到架构-知乎 Live 学习整理
    SEO配置信息操作文档
    函数常见的写法及调用方法整理
    电脑中‘落雪’木马病毒如何解决
    Nuxt学习笔记
  • 原文地址:https://www.cnblogs.com/Finley/p/5469206.html
Copyright © 2011-2022 走看看