学习->C++篇十二:stack,queue,priority_queue的实现

目录

1.容器适配器

2.priority_queue的模拟实现


1.容器适配器

适配器是一种设计模式,该模式是将一个类的接口转换成客户希望的另外一个接口。在数据结构实现时,可以采用不同的容器来适配同一数据结构,比如堆,栈,队列的实现。
例如:stack和queue的模拟实现
#pragma once
#include<deque>
using std::deque;
template<class T,class Container= deque<T>>
class stack
{
public:
	stack() {}
	void push(const T& x) { _c.push_back(x); }
	void pop() { _c.pop_back(); }
	T& top() { return _c.back(); }
	const T& top()const { return _c.back(); }
	size_t size()const { return _c.size(); }
	bool empty()const { return _c.empty(); }
private:
	Container _c;
};

template<class T, class Container = deque<T>>
class queue
{
public:
	queue() {}
	void push(const T& x) { _c.push_back(x); }
	void pop() { _c.pop_front(); }
	T& back() { return _c.back(); }
	const T& back()const { return _c.back(); }
	T& front() { return _c.front(); }
	const T& front()const { return _c.front(); }
	size_t size()const { return _c.size(); }
	bool empty()const { return _c.empty(); }
private:
	Container _c;
};

        stack和queue使用deque作为默认的适配容器,原因是deque是一个双端队列的结构,它的头尾的插入和删除的效率很高,恰好适合这两个不需要在中间插入删除的数据结构,但是deque的底层结构也有缺陷,deque的底层结构可以看做是是分段连续的数组,故在遍历时需要检测每个数组的边界,故deque的随机访问效率是不如vector的,故deque的用途不广。

2.priority_queue的模拟实现

        优先队列是用数组模拟实现的,故默认用支持快速随机访问的容器vector为佳。还需要一个用于比较元素大小的仿函数,库中的默认仿函数为less<T>,默认建的是大堆。仿函数其实是一个类模板,类重载了()这个运算符,故可以像看起来函数一样去调用operator()实现元素的大小比较。

模拟实现:

#include<vector>
using std::vector;
using std::swap;
//less<T> 建的是大堆
template<class T>
struct less
{
	bool operator()(const T& e1, const T& e2)
	{
		return e1 < e2;
	}
};

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

template<class T, class Container = std::vector<T>, class Compare = less<T>>
class priority_queue
{
public:
	priority_queue() = default;
	template<class Iterator>
	priority_queue(Iterator first, Iterator last)
		:_c(first,last)
	{
		int parent = (_c.size() - 2) >> 1;
		while (parent >= 0)
			AdjustDown(parent--);
	}

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

	void pop()
	{
		std::swap(_c.front(), _c.back());
		_c.pop_back();
		AdjustDown(0);
	}

	size_t size()const { return _c.size(); }
	const T& top()const { return _c.front(); }
	bool empty()const { return _c.empty(); }
private:
	void AdjustDown(int parent)
	{
		int child = parent * 2 + 1;
		while (child < _c.size())
		{
			if (child + 1 < _c.size()
				&& Compare()(_c[child], _c[child + 1]))
				++child;
			if (Compare()(_c[parent], _c[child]))
			{
				swap(_c[parent], _c[child]);
				parent = child;
				child = parent * 2 + 1;
			}
			else
				return ;
		}
	}

	void AdjustUp(int child)
	{
		int parent = (child - 1) >> 1;
		while (child)
		{
			if (Compare()(_c[parent], _c[child]))
			{
				swap(_c[parent], _c[child]);
				child = parent;
				parent = (child - 1) >> 1;
			}
			else
				return;
		}
	}
private:
	Container _c;
};

简易测试:

int main() 
{
	priority_queue<int>pq;
	pq.push(5243);
	pq.push(23);
	pq.push(312);
	pq.push(35);
	pq.push(567);
	pq.push(878);
	pq.push(9994);

	while (!pq.empty())
	{
		cout << pq.top() << endl;
		pq.pop();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值