初学算法-基于最小堆的优先级队列C++实现

笔者近日实现了最小堆类及其派生的优先级队列,特将代码奉上,不足之处还请指出!

在实现优先级队列时,笔者表示萌萌哒没有用过template写派生类,结果写完了出现error: *** was not decleared in this scope。。后来各种补上this->才完事,在CSDN(笔者的帖子地址? http://bbs.csdn.net/topics/391806995)上提问后才知道是模板参数依赖,笔者表示涨姿势了。。

/**
 * The Minimum Heap Class and Heap Sort in C++
 * Thanks to Introduction to Algorithms (CLRS) Chapter 6
 * Thanks to Tsinghua MOOC of "Data Structure and Algorithms"
 * Author: Zheng Chen / Arclabs001
  * Email : [email protected]
 * Copyright 2015 Xi‘an University of Posts & Telecommunications. All rights reserved.
 */
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#define INF 0xFFFFFFF
using namespace std;

template<class T>
class Min_Heap
{
private:
    vector<T> A;
    int _size;   //The size of heap

    int parent(int i) { return (i-1)/2; }  //Get the index of ith parent
    int left(int i)   { return 2*i+1; }    //Get the index of ith left child
    int right(int i)  { return 2*i+2; }    //Get the index of ith right child

public:
    //Here are three different constructor
    Min_Heap() {A.clear(); A.reserve(100); _size=0;}
    Min_Heap(vector<T> _array)
    {
        _size = 0;
        A.clear(); A.reserve(_array.size()*2);
        for(int i=0; i<_array.size(); i++)
        {
            A.insert(A.end(), _array[i]);
            _size++;
        }

        for(int i=(_size-1)/2; i>=0; i--)
        {
            Min_Heapify(i);
        }
    }
    Min_Heap(T* _array, int array_size)
    {
        _size = 0;
        A.clear(); A.reserve(array_size*2);
        for(int i=0; i<_size; i++)
        {
            A.insert(A.end(), _array[i]);
            _size++;
        }

        for(int i=(_size-1)/2; i>=0; i--)
        {
            Min_Heapify(i);
        }
    }

    void Min_Heapify(int i)
    {
        int smallest;
        int l = left(i);
        int r = right(i);

        if(l<_size && A[l]<A[i]) smallest = l;
        else smallest = i;
        if(r<_size && A[r]<A[smallest]) smallest = r;

        if(smallest != i)
        {
            swap(A[i],A[smallest]);
            Min_Heapify(smallest);
        }
    }

    //The Heap Sort function
    //Final status : The array A‘s element in desending order.
    void sort()
    {
        for(int i=_size-1; i>0; i--)
        {
            swap(A[0],A[i]);
            --_size;
            Min_Heapify(0);
        }
    }

    T& pop()
    {
        --_size;
        T *tmp = new T;
        *tmp = A[0];
        swap(A[0],A[_size]);
        Min_Heapify(0);
        return *tmp;
    }

    void push(const T &key)
    {
        A.insert(A.end(),INF);
        _size++;

        int i = _size-1;
        while(i>0 && key < A[parent(i)])
        {
            A[i] = A[parent(i)];
            i = parent(i);
        }
        A[i] = key;
    }

    void _delete(int i)  //delete the ith element
    {
        swap(A[i],A[_size-1]);
        --_size;
        A.erase(A.begin()+_size);
        Min_Heapify(i);
    }

    bool decrease_key(int i, const T &key)
    {
        if(key > A[i])
        {
            return false;
        }

        while(i>0 && key < A[parent(i)])
        {
            A[i] = A[parent(i)];
            i = parent(i);
        }
        A[i] = key;
        return true;
    }

    void showHeap()
    {
        for(int i=0; i<_size; i++)
        {
            cout<<A[i]<<" ";
        }
        cout<<endl;
    }

    void showAll()
    {
        for(int i=0; i<A.size(); i++)
        {
            cout<<A[i]<<" ";
        }
        cout<<endl;
    }
};

int main()
{
    vector<int> A;
    A.clear();
    A.reserve(20);

    srand((unsigned int)time(0));
    for(int i=0; i<10; i++)
        A.insert(A.end(),rand()%1000);
    Min_Heap<int> heap(A);
    heap.showHeap();
    heap.decrease_key(5,0);
    heap.showHeap();
    heap.sort();
    heap.showAll();
    heap._delete(3);
    heap.showAll();
    return 0;
}

这个是优先级队列:

/**
 * The Priority Queue Class in C++
 * Thanks to Introduction to Algorithms (CLRS) Chapter 6
 * Author: Zheng Chen / Arclabs001
 * Email : [email protected]
 * Copyright 2015 Xi‘an University of Posts & Telecommunications. All rights reserved.
 */
#include "myheap.h"
#define INF 0xFFFFFFF
using namespace std;

template <class T>
class Priority_Queue: public Min_Heap<T>
{
public:
    Priority_Queue(): Min_Heap<T>() {}
    Priority_Queue(vector<T> _array):Min_Heap<T>(_array) {}
    Priority_Queue(T *_array, int array_size): Min_Heap<T>(_array, array_size) {}

    T& minimum() {return this->A[0];}
    T& pop()
    {
        --this->_size;
        T *tmp = new T;
        *tmp = this->A[0];
        swap(this->A[0],this->A[this->_size]);
        this->Min_Heapify(0);
        return *tmp;
    }

    bool decrease_key(int i, const T &key)
    {
        if(key > this->A[i])
        {
            return false;
        }
        this->A[i] = key;
        while(i>0 && this->A[i]<this->A[this->parent(i)])
        {
            swap(this->A[i],this->A[this->parent(i)]);
            i = this->parent(i);
        }
        return true;
    }

    void push(const T &key)
    {
        this->A.insert(this->A.end(),INF);
        this->_size++;

        int i = this->_size-1;
        while(i>0 && key < this->A[this->parent(i)])
        {
            this->A[i] = this->A[this->parent(i)];
            i = this->parent(i);
        }
        this->A[i] = key;
    }
};

int main()
{
    vector<int> A;
    A.clear();
    A.reserve(20);

    srand((unsigned int)time(0));
    for(int i=0; i<10; i++)
        A.insert(A.end(),rand()%1000);

    Priority_Queue<int> pq(A);
    pq.show();
    pq.push(rand()%1000);
    pq.show();
    pq.pop();
    pq.show();
    pq.decrease_key(5,0);
    pq.show();
    return 0;
}
时间: 2024-12-15 13:08:07

初学算法-基于最小堆的优先级队列C++实现的相关文章

STL源码笔记(15)—堆和优先级队列(二)

STL源码笔记(15)-堆和优先级队列 优先级队列的源码实现基于heap的操作,底层容器默认是vector. 优先级队列简介 优先级队列跟队列类似,一端插入一端删除,不同的是,优先级队列的元素入队后会根据其优先级进行调整,默认情况下优先级高的将优先出队,在SGI STL中,优先级队列的功能保证由heap实现:stl_heap.h中,heap的分析见:STL堆源码分析 优先级队列构造函数 默认情况下,优先级队列使用vector作为底层容器,使用less作为比较函数,其在源码中的定义声明如下: te

STL源码笔记(14)—堆和优先级队列(一)

STL源码笔记(14)-堆和优先级队列 priority_queue是拥有权值观念的queue,跟queue类似,其只能在一端push,一端pop,不同的是,每次push元素之后再容器内部元素将按照一定次序排列,使得pop得到的元素始终是当前权值的极大值. 很显然,满足这个条件就需要某些机制了,缺省情况下使用max-heap大顶堆来实现,联想堆排序的实现,使用大顶完成序列从小到大的排序,过程大概是: 把堆的根元素(堆中极大值)交换到最后 堆的长度减1 这样每次取出堆中的极大值完成排序,刚好与优先

python[数据]--队列,堆,优先级队列

队列:from collections import deque:实现保存最后几条历史记录,list = deque(maxlen=6),那么超过六条记录会删除之前的记录. 堆:import heapq;最大特点是第一弹出的元素总是堆中最小的元素:list=[1,2,3] heap=heapq.heapify(list) ,nlargest(3,数据,key=lambda) nsmallest() 优先级队列:堆中的元素(-优先级,序号,item)这样即可实现优先级,优先级越高最先pop出堆,优

java最小堆实现优先权队列和求最大的n个数问题

堆在实现优先权队列和求最大最小的n个数问题上,有着莫大的优势! 对于最大堆和最小堆的定义此处不再赘述,课参考网上文章:http://blog.csdn.net/genios/article/details/8157031 本文主要是对最小堆进行实现和应用,仅供新手参考. 优先权队列 优先权队列是一种非常有用的数据结构,操作系统的进程调度就有优先权队列的应用,如果用最小值表示最高的优先权,则使用最小堆,否则使用最大堆. top-N值为问题: 对于求最大的n个数,可以用最小堆来实现,思路是:将n个数

个推基于 Apache Pulsar 的优先级队列方案

作者:个推平台研发工程师 祥子 一.业务背景 在个推的推送场景中,消息队列在整个系统中占有非常重要的位置.当 APP 有推送需求的时候, 会向个推发送一条推送命令,接到推送需求后,我们会把APP要求推送消息的用户放入下发队列中,进行消息下发:当同时有多个APP进行消息下发时,难免会出现资源竞争的情况, 因此就产生了优先级队列的需求,在下发资源固定的情况下, 高优先级的用户需要有更多的下发资源. 二.基于 Kafka 的优先级队列方案 针对以上场景,个推基于 Kafka 设计了第一版的优先级队列方

经典白话算法之优先级队列

<1>概念 优先级队列,顾名思义,就是一种根据一定优先级存储和取出数据的队列.它可以说是队列和排序的完美结合体,不仅可以存储数据,还可以将这些数据按照我们设定的规则进行排序.优先级队列是堆的一种常见应用.有最大优先级队列(最大堆)和最小优先级队列(最小堆).优先级队列是一种维护有一组元素构成的集合S的数据结构. <2>优先队列支持的基本运算 [cpp] view plaincopy //建立一个保存元素为int的优先级队列,其实是建了一个小顶堆 //但是请特别注意这样的建的堆默认是

优先级队列(PriprityQueue)是一种什么样的数据结构

优先级队列(PriprityQueue)是一种无界队列,基于优先级堆,它的元素根据自然顺序或者通过实现Comparator接口的自定义排序方式进行排序.这篇文章,我们将创建一个Items的优先级队列,基于价格排序,优先级队列用来实现迪科斯彻算法(Dijkstra algorithm)非常实用.值得注意的是他的迭代器并不保证有序,如果需要按顺序遍历,最好使用Arrays.sort(pd.toArray())方法.同时它的实现不是同步的,意味着在多线程中不是线程安全的对象,可以取而代之的是Prior

数据结构与算法之美-堆的应用

堆的应用一:优先级队列 优先级队列首先应该是一个队列.队列最大的特性就是先进先出.但是在优先级队列中,出队顺序不是先进先出,而是按照优先级来,优先级最高的,最先出队. 用堆来实现优先级队列是最直接.最高效的.这是因为,堆和优先级队列非常相似.一个堆就可以看作一个优先级队列.很多时候,它们只是概念上的区分而已. 往优先级队列中插入一个元素,就相当于往堆中插入一个元素.从优先级队列中取出优先级最高的元素,就相当于取出堆顶元素. 很多数据结构和算法都要依赖它.比如,赫夫曼编码.图的最短路径.最小生成树

有序链表实现的优先级队列

package day1_29; public class Link { public long dDate; public Link next; public Link(long dDate){ this.dDate = dDate; } //打印链结点的方法 public void displayLink(){ System.out.println("["+dDate+"]"); } } =====================================