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

先看一下STL中优先级队列实现的功能:
这里写图片描述

一、介绍优先级队列

优先级队列就是每次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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值