模拟实现(优先级队列)priority_queue:优先级队列、仿函数、 反向迭代器等的介绍-一、优先级队列

优先级队列本质是一个堆,使用vector容器进一步改进进行实现,优先级队列可以传入比较模板参数,来确定建立大根堆还是小根堆, 比较模板参数本质上是一个仿函数。

namespace hhb
{

	template<class T>
	struct Less
	{
		bool operator()(const T& left, const T& right)
		{
			return (left < right);
		}
	};

	template<class T>
	struct Greater
	{
		bool operator()(const T& left, const T& right)
		{
			return (left > right);
		}
	};

	template <class T, class Container = vector<T>, class Compare = Less<T>>
	class priority_queue
	{
		
	private:
		void AdjustDown(int parent)
		{

			Compare _com;

			// 找到子节点
			int child = parent * 2 + 1;
			// 找字节点中大的一个
			if (child + 1 < _con.size() && _com(_con[child], _con[child + 1]))
			{
				++child;
			}

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


		}

		void AdjustUp(int child)
		{
			Compare _com;
			// 找到父节点
			int 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;
				}
			}

		}
	public:

		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--)
			{
				AdjustDown(i);
			}
			
		}

		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);
		}


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

		const T& top()
		{
			return _con.front();
		}

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

	private:
		Container _con;
	};
}

测试:

#include <iostream>
#include <vector>

using namespace std;

#include "Priority_queue.h"

void test_priority_queue1()
{
	hhb::priority_queue<int> pq1;
	pq1.push(3);
	pq1.push(1);
	pq1.push(5);
	pq1.push(2);
	pq1.push(4);


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


	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(4);
	v.push_back(3);
	v.push_back(5);


	hhb::priority_queue<int> pq2(v.begin(), v.end());

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

	cout << endl;
}


void test_priority_queue2()
{
	//Less<int> less;
	//cout << less(1, 2) << endl;

	hhb::priority_queue<int, vector<int>, hhb::Less<int>> pq1;
	pq1.push(1);
	pq1.push(2);
	pq1.push(3);
	pq1.push(4);
	pq1.push(5);



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


	hhb::priority_queue<int, vector<int>, hhb::Greater<int>> pq2;
	pq2.push(5);
	pq2.push(4);
	pq2.push(3);
	pq2.push(2);
	pq2.push(1);


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

}

class Date
{
public:
	Date(int year = 1949, int month = 10, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{}

	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

	bool operator<(const Date& d) const
	{
		if (_year < d._year)
		{
			return true;
		}
		else if (_year == d._year && _month < d._month)
		{
			return true;
		}
		else if (_year == d._year && _month == d._month && _day < d._day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	bool operator>(const Date& d) const
	{
		if (_year > d._year)
		{
			return true;
		}
		else if (_year == d._year && _month > d._month)
		{
			return true;
		}
		else if (_year == d._year && _month == d._month && _day > d._day)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	friend ostream& operator<<(ostream& out, const Date& d);


private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << '-' << d._month << '-' << d._day;
	return out;
}


void test_priority_queue3()
{
	hhb::priority_queue<Date, vector<Date>, hhb::Less<Date>> pq1;

	pq1.push(Date(2024, 9, 23));
	pq1.push(Date(2024, 10, 23));
	pq1.push(Date(2024, 8, 23));

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


	hhb::priority_queue<Date, vector<Date>, hhb::Greater<Date>> pq2;

	pq2.push(Date(2024, 9, 23));
	pq2.push(Date(2024, 10, 23));
	pq2.push(Date(2024, 8, 23));

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

}

int main()
{

	//test_priority_queue1();

	//test_priority_queue2();

	 test_priority_queue3();

	return 0;
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上一篇:Android常用C++特性之std::move


下一篇:基于SpringBoot+Vue+MySQL的美食点餐管理系统-技术介绍