C++ --优先级队列模拟实现

本文详细介绍了C++中的priority_queue类模板,探讨了其模板参数Compare的作用,展示了如何通过less和greater模板实现不同堆序,以及push、pop、调整操作的原理。通过实例演示了如何创建并操作一个优先级队列。
摘要由CSDN通过智能技术生成

优先级队列:priority_queue

在这里插入图片描述

	template <class T,class Container=vector<T>,class Compare = less<T>>
	class priority_queue
	{
	public:


	private:
		Container _con;
		Compare com;
	};
}

我们先来介绍一下priority_queue的类模板的第三个模板参数

class Compare = less<T>

这里的Compare我们给这个类模板参数一个缺省值

这个缺省值为仿函数

template<class T>
	struct less
	{
		bool operator()(const T& l, const T& r)
		{
			return l < r;
		}
	};

	template<class T>
	struct greater
	{
		bool operator()(const T& l, const T& r)
		{
			return l > r;
		}
	};

仿函数的本质:就是重载operator(),并给两个参数,使这个类能像函数一样去使用。

我们先一口气把几个简单的函数直接给出

	bool empty() const
		{
			return _con.empty();
		}
	size_t size() const
		{
			return _con.size();
		}
	const T& top() const
		{
			return _con[0];
		}

优先级队列:底层采用大小堆的方式(物理结构是vector),对push的数据进行大小排序
所以在push数据的时候,如果我们采用less这个类模板类型,则采用大堆存储,也就是当从头结点出数据的时候,会是一个降序的。传入greater的时候就恰恰相反。

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

		void push(const T& x)
		{
			_con.push_back(x);
			AdjustUp(_con.size() - 1);
		}

我们将节点插入队尾,并进行向上调整,使之成为一个大堆(less)或者小堆(greater),这里的仿函数就是用来控制大小判断的。

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

				if (com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

		void pop()
		{
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AdjustDown(0);
		}

删除数据时,先将队头的数据和最后一个数据交换,然后进行vector的pop_back(),就可以删除数据了。其中交换后,除了堆顶以外,它的孩子会形成两个大堆(小堆),我们对其进行向下调整,就会等到完整的大小堆。

我们进行测试:


int main()
{

	www::priority_queue<int> pq;

	pq.push(1);
	pq.push(2);
	pq.push(3);
	pq.push(4);
	pq.push(5); 
	while (!pq.empty())
	{
		cout << pq.top() << " ";
		pq.pop();
	}
	cout << endl;
	return 0;
}


在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值