【C++StackQueue】适配器,仿函数,优先级队列

目录

 适配器

优先级队列(priority_queue):

仿函数 -- 函数对象 这个类的对象可以像函数一样去使用

 priority_queue实现

deque 


适配器和仿函数 

栈和队列的特性:

 适配器

概念:适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总 结),该种模式是将一个类的接口转换成客户希望的另外一个接口(复用);

让我们先观察一下库里面queue和stack的实现:

适配器:class Compare = less<typename Container::value_type>

找容器里面的value_type就是T;为什么要加typename,未实例化会找不到,用typename声明

容器适配器stack实现:

#pragma once
#include<iostream>
#include<vector>
#include<deque>
using namespace std;
//namespace lj
//{
//	常规方法
//	template<class T>
//	class stack
//	{
//	public:
//
//	private:
//		T* _a;
//		size_t _size;
//		size_t _capacity;
//	};
//}
namespace lj
{
	template<class T, class Container = deque<T>>
	class stack
	{
	public:
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		T top()
		{
			return _con.back();
		}
	private:
		Container _con;
	};
}

容器适配器queue实现:

#pragma once
#include<deque>
using namespace std;
namespace lj
{
	// list
	template<class T, class Container = deque<T>>
	class queue
	{
		void push(const T& x)
		{
			_con.push_back(x);
		}

		void pop()
		{
			_con.pop_front();
		}

		T front()
		{
			return _con.front();
		}

		T back()
		{
			return _con.back();
		}

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

		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

优先级队列(priority_queue):

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成 堆的结构,因此priority_queue就是堆(不是队列),需要获取最大(最小)多少个(TOPK问题),都可以考虑使用priority_queue。注意: 默认情况下priority_queue是大堆。

优先级队列的使用:

仿函数 -- 函数对象 这个类的对象可以像函数一样去使用

struct LessInt//类
{
	bool operator()(const int& l, const int& r)
	{
		return l < r;
	}
};

bool LessFunc1(int l, int r)//全局函数
{
	return l < r;
}

int main()
{
	cout << LessFunc1(1, 2) << endl;;

	LessInt LessFunc2;
	cout << LessFunc2(3, 4) << endl;
	// 转换成下面的调用
	cout << LessFunc2.operator()(3, 4) << endl;
	return 0;
}

 priority_queue实现

priority的底层是vector,把新元素尾插到数组,每向上调整(时间复杂度O(longN)),堆顶元素一定最小或最大,按数组不一定是升序和降序;

void AdjustUp(size_t child)
		{
			Compare com;

			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[parent] > _con[child])
				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);
		}

删除(pop):如果直接删堆顶的数据,会把建好的堆打乱,需要重新建堆(时间复杂度:O(N))

解决:堆顶和最后一个数交换尾删,向下调整(时间复杂度O(N)),因为左右子树有序

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

				//if (_con[parent] > _con[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();

			AdjustDwon(0);
		}

完整代码

#include<vector>
namespace LDJ
{
	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;
		}
	};

	template<class T, class Container = std::vector<T>, class Compare = less<T>>
	class priority_queue
	{
	public:
		//typedef typename Container::value_type VT;

		void AdjustUp(size_t child)
		{
			Compare com;

			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				//if (_con[parent] > _con[child])
				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);
		}

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

				//if (_con[parent] > _con[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();

			AdjustDwon(0);
		}

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

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

		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值