优先级队列的简易实现

本文介绍了如何使用C++模板实现了一个优先级队列,基于堆数据结构,可以按照升序或降序排列元素。队列支持调整元素位置,通过仿函数控制比较规则。
摘要由CSDN通过智能技术生成

1、优先级队列是一个容器适配器,功能是能根据预先设定规则,在插入时将元素排列,如让元素升序降序等,采用的数据结构时堆,底层是vector(也可以用用户自己设计的序列式容器)。以下是一个优先级队列的简易实现,包含一个堆的向下调整及向上调整函数,以及仿函数的利用。

#include<iostream>
#include<vector>
using namespace std;

namespace k
{
	template<class T>
	struct less
	{
		bool operator()(T& a, T& b)
		{
			return a < b;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(T& a, T& b)
		{
			return a > b;
		}
	};

	template<class T, class Container = vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		void AdjustUp(int child)
		{
			Compare cpr;
			while (child)
			{
				int prt = (child - 1) / 2;
				if (cpr(_con[prt], _con[child]))
				{
					swap(_con[child], _con[prt]);
				}
				else
				{
					break;
				}
				child = prt;
			}
		}
		void AdjustDown(int prt)
		{
			Compare cpr;
			int child = prt * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && cpr(_con[child], _con[child + 1]))
				{
					child++;
				}
				if (cpr(_con[prt], _con[child]))
				{
					swap(_con[prt], _con[child]);
					prt = child;
					child = prt * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}
		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);
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
		T top()
		{
			return _con[0];
		}
	private:
		Container _con;
	};
}

        可以看到priority_queue有三个模板参数,第一个是元素类型T,第二个是容器类型container,第三个是用于进行比较的仿函数的类型,有大于和小于,通过控制仿函数的类型,我们可以控制vector是大堆还是小堆。

2、什么是仿函数?

        仿函数又叫函数对象,因为单看他的使用,你会以为他是一个函数,实际上是设计了一个类,这个类一般没有成员变量(所以类的大小为1字节),并且为这个类重载了括号运算符用于实现一些计算。如上面的优先级队列的仿函数,实现了两个,大于和小于,在用于比较时,定义一个仿函数对象,直接调用operator()即可。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值