【C++ 初阶】优先级队列(Priority_Queue)底层框架模拟实现

目录

  • 一、priority_queue介绍
  • 二、priority_queue使用
  • 三、模拟实现
  • 四、完整代码

一、priority_queue介绍

cplusplus官网 : priority_queue的说明

在这里插入图片描述

优先级队列和普通的队列不是一个概念,普通的queue遵守先进先出的规则,而优先级队列遵守优先级最高的先出,本质上就是堆排

二、priority_queue使用

我们给上一组数据,调用top函数进行打印输出发现最大值优先输出,默认降序
【C++ 初阶】优先级队列(Priority_Queue)底层框架模拟实现_第1张图片
如果要排成升序呢?
【C++ 初阶】优先级队列(Priority_Queue)底层框架模拟实现_第2张图片
官网提供了模版参数,我们发现这里传的不是类型而是对象,如果要排升序通过传greater,默认是less
在这里插入图片描述

三、模拟实现

我们在实现前需要注意,模版是不支持分离编译的,因此我们在hpp里面进行声明和定义

首先默认创建一个大堆,这里就不再赘述概念,可以参考下面的链接
堆排详细说明

【C++ 初阶】优先级队列(Priority_Queue)底层框架模拟实现_第3张图片

 //大堆
    template<class T, class Container = vector<T>, class Compare = Less<T>  >
    class priority_queue{
    public:
            void push(const T& x){
            _con.push_back(x);
            AdjustUp(_con.size() - 1); //向上调整保持大堆状态
        	}

	        void pop(){
            swap(_con[0], _con[_con.size()-1]);	//头尾交换,向下调整
            _con.pop_back();
            AdjustDown(0);
   			}
  	private:
        Container _con;         
   }

下面是向上和向下调整函数实现,注意默认的是Less类模版

void AdjustUp(size_t child){
	size_t parent = (child-1)/2;
	while(child > 0){
		if(_con[child] > _con[parent]){
			swap((_con[child] > _con[parent]);
			child = parent;
			parent = (child-1)/2;
		}else{
			break;
		}
	}
}

void AdjustDown(size_t parent){
	int child = parent*2 + 1;
	while(child < _con.size()){
		if(child < _con.size() && _con[child] < _con[child+1] ){
			child++;
		}
		if(_con[parent] < _con[child]){
			swap(_con[parent], _con[child] );
			parent = child;
			child = parent * 2 + 1;
		}else{
			break;
			}
	}
}

这里在构造函数的时候就需要建堆了

//默认构造,不用写什么,会自动调用构造函数
priority_queue(){}

//带参构造
template<class InputIterator>
priority_queue(InputIterator first, InputIterator last){
    //数据插入
    while(first != last){
        _con.push_back(*first);
        ++first;
    }
    
    //建堆
    for(int i= (_con.size()-1-1) / 2 ; i >= 0; --i){ // size()-1 是最后一个数据的下标,父亲的话再-1 ,除2
        AdjustDown(i);
    }
}

最后我们考虑一个问题:
解决完大堆的实现后,如果在不修改符号的情况下变小堆呢?
所以就有了仿函数的概念
【C++ 初阶】优先级队列(Priority_Queue)底层框架模拟实现_第4张图片

//仿函数/函数对象,可以像函数一样去使用

//建大堆,排升序
class Less{
public:
    bool operator()(const T& x, const T& y){
        return x < y;
    }
};
//建小堆,排降序
template<class T>
class Greater{
public:
    bool operator()(const T& x, const T& y){
        return x > y;
    }
};

四、完整代码

Gitee链接

priority_queue simulation

创作不易,如果文章对你帮助的话,点赞三连哦:)

你可能感兴趣的:(C++,c++,开发语言,后端)