欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

堆得应用【一】--【优先级队列priority_queue】

程序员文章站 2022-03-31 20:01:54
...

先看一下STL中优先级队列实现的功能:
堆得应用【一】--【优先级队列priority_queue】

一、介绍优先级队列

优先级队列就是每次top可以取到队列的最值;每次pop都能删除队列中的最值;
那么我们应该如何实现呢?

优先级队列是我们常见的数据结构队列的一种变形,对于队列,大家都很熟悉;就是先进如队列的元素,先出队列,那么一般的队列是可以尾插,可以头删,可以取到头部的元素,,可以到尾部取元素;我们要将一般队列实现优先级队列有三种方法:
方法一:就是我们在插入数据【push】时候,每次从集合中找到一个最值,尾插到队列中,这样经过n次那么集合中的m个数据就会按照顺序装入队列中,所以插入的时间复杂度【O(N^2)】,那么这种情况,我们取队列的最值,只要取头部【Top】的元素,就可以取到,时间复杂度【O(1)】;我们删除【Pop】队列的最值,也只要删除头部元素即可,时间复杂度【O(1)】;

方法二:我们可以每次将几个中的元素按照集合的顺序依次插入【Push】队列中,那么时间复杂度为O(N);这时在取队列的最值【Top】时,我们就要每次将队列的元素遍历一遍才能找到最值删除队列【Pop】的最值,也是将队列的元素找一遍,找到最值才能删除而且这样由于队列只能查看头部元素和尾部元素,那么在寻找最值的时候,还要pop掉头部元素,才能查看下一个元素,;而且在找完之后还要在将删除的元素装入队列,所以时间复杂度更高,所以这种方法太挫;不选;

方法三:就是我们不用队列的数据结构实现优先级队列;
我们用堆得数据【Heap】结构实现优先级队列;
【Push】时,直接将数据push进堆里;时间复杂度O(logN);
【Top】时,直接从堆中拿最顶端的元素(即数组下标为0的元素),时间复杂度O(1);
【Pop】时,直接从堆中删除最值元素,即数组的第一个元素,时间复杂度O(logN);

二、代码实现:

#include<iostream>
using namespace std;
#include"Heap.h"

template<typename T,typename Compare>
class PriorityQueue
{
public:
    PriorityQueue(const T* arr,int sz)
        :_heap(arr,sz)
    {}
    void Push(const T& x)//向优先级队列中添加元素
    {
       _heap.Push(x);
    }
    void Pop()//删除优先级最高的元素--即最大元素或者最小元素
    {
       _heap.Pop();//删除堆得0小标元素,然后向下调整堆
    }
    const T& Top()//返回优先级队列最高的元素--即最大元素或者最小元素
    {
       return _heap.Top();//返回堆得第一个元素
    }
    size_t Szie()//返回优先级队列的元素个数
    {
       return _heap.Size();//返回堆得元素个数
    }
    bool Empty()//判断优先级队列是否为空
    {
       return _heap.Empty();
    }
private:
    Heap<T,Compare> _heap;
};

int main()
{
      int a [] = {10,11, 13, 12, 16, 18, 15, 17, 14, 19};
      int sz=sizeof(a)/sizeof(a[0]);
      PriorityQueue<int,Small<int>> pq(a,sz);
      cout<<pq.Top()<<endl;
      cout<<pq.Szie()<<endl;
      cout<<pq.Empty()<<endl;


      pq.Push(2);
      cout<<pq.Top()<<endl;
      cout<<pq.Szie()<<endl;
      cout<<pq.Empty()<<endl;

      pq.Pop();
      cout<<pq.Top()<<endl;
      cout<<pq.Szie()<<endl;
      cout<<pq.Empty()<<endl;
}
相关标签: 优先级队列prior