c++--模拟实现优先队列

  priority_queue的底层结构就是堆,因此此处只需对对进行通用的封装即可。

创建一个priority_queue类,这里的Compar是为了增加仿函数。

这个类中会实现堆的push,pop,top,empty,size等接口

首先完成默认构造和使用迭代器构造

这里的迭代器构造在插入后就完成建堆,使用的是向下调整,向下调整的空间复杂度会比向上调整的要简单,减少消耗。

向下调整这里使用的是假设孩子法来确定要交换孩子的下标,交换以后再将父亲和孩子下标更新,进行从上到下的调整,如果比较失效就跳出循环,建堆完成。这里并没有直接使用大于小于,而是使用了一个Compar 类的对象comfunc将参数传进去进行比较,Compar可以以模板的形式传入不同的类型,达到建大堆或者小堆的操作。

这两个就是比较类,重载了()传参数进行比较返回bool值

这里实现了push的操作,需要先将数据进行尾插,然后从尾进行向上调整

向上调整也是和向下调整类似父子的方式进行实现

Pop的实现先将头部数据和尾部数据进行交换,然后再尾删,再进行向下调整,而不是直接进行头删,这样会导致堆的结构被破坏

top,empty,size是直接调用容器中的接口进行实现

完整代码

#pragma once
#include<iostream>
#include<deque>
#include<vector>
using namespace std;

namespace PY
{
	template<class T>
	struct myless
	{
		bool operator()(const T& x, const T& y)
		{
			return x < y;
		}
	};

	template<class T>
	struct mylgreater
	{
		bool operator()(const T& x, const T& y)
		{
			return x > y;
		}
	};

	template<class T,class Container=vector<T>,class Compar=myless<T>>
	class priority_queue
	{
	public:
		priority_queue() = default;

		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--)//从最后一个非叶子节点开始调整
			{
				ajust_down(i);
			}
		}

		void ajust_up(int child)//向上调整
		{
			Compar comfunc;
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (comfunc(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent= (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}

		void ajust_down(int parent)//向下调整
		{
			Compar comfunc;
			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				if (child + 1 < _con.size() && comfunc(_con[child], _con[child+1]))
				{
					++child;
				}
				if (comfunc(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
			}
		}

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

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

			ajust_down(0);
		}

		const T& top()
		{
			return _con[0];
		}

		size_t size()
		{
			return _con.size();
		}

		bool empty()
		{
			return _con.empty();
		}

	private:
		Container _con;
	};
}

测试代码

// 默认是大堆
void test_priority_queue()
{
	vector<int> v = { 3,2,7,6,0,4,1,9,8,5 };
	PY::priority_queue<int> q1;
	for (auto& e : v)
		q1.push(e);

	while (!q1.empty())
	{
		cout << q1.top() << " ";
		q1.pop();
	}
	cout << endl;
}

void test_priority_queue2()
{
	vector<int> v = { 1, 5,3,8,7,6};
	PY::priority_queue<int> q1(v.begin(),v.end());
	
	while (!q1.empty())
	{
		cout << q1.top() << " ";
		q1.pop();
	}
	cout << endl;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值