实现最小栈和优先队列

基础栈的实现

用到模板    template<class T,class Container>,Container是某个适配器(list,vector)。

原理是通过调用list或vector的函数实现尾插,尾删(list和vector都有push_back和pop_back函数)。

	template<class T,class Container>
	class stack  //  尾插尾删
	{
	public:
		void pop()
		{
			_con.pop_back();
		}
		void push(const T& val)
		{
			_con.push_back(val);
		}
		size_t size()
		{
			return _con.size();
		}
		T& top()
		{
			return _con.back();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};

最小栈

功能:获取最小的数

	template<class T,class Container>
	class Minstack
	{
	public:
		void push(const T& val)
		{
			
			if (_min.empty() || val < _min.top())  //  当小栈为空或者栈顶数大于Push的数,入小栈
			{
				_min.push(val);
			}
			_elem.push(val);
		}
		void pop()
		{
			if (!_min.empty() && _min.top() == _elem.top())  //当小栈非空并且删除的数等于栈顶的数,出小栈
			{
				_min.pop();
			}
			_elem.pop();

		}
		T& GetMin()
		{
			return _min.top();
		}

	private:
		Container _elem;  //  两个栈,一个正常栈,一个小栈(栈顶存的是最小的数,栈顶下一个存的是第2小的数......)
		Container _min;
	};

测验

void test3()
{
	Minstack<int, stack<int,vector<int>>> minst;  //用的是自己实现的栈
	minst.push(4);
	minst.push(6);
	minst.push(2);
	minst.push(7);
	minst.push(1);
	minst.push(0);

	cout << minst.GetMin() << endl;
	minst.pop();

	cout << minst.GetMin() << endl;
	minst.pop();

	cout << minst.GetMin() << endl;
	minst.pop();

	cout << minst.GetMin() << endl;
	minst.pop();

	cout << minst.GetMin() << endl;
	minst.pop();
}

输出:
0
1
2
2
4

基础队列

	template<class T, class Container>
	class Queue   // 先进先出(头插,尾删) 由于vector是数组,支持随机访问,所以没有头插头删  用list作Queeu的适配器更合适
	{
	public:
		void pop()
		{
			_con.pop_back();
		}
		void push(const T& val)
		{
			_con.push_front(val);
		}
		T& head()
		{
			return _con.front();
		}
		bool empty()
		{
			return _con.empty();
		}

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

	private:
		Container _con;
	};

测试

void test2()
{
	Queue<int, list<int>> qu;
	qu.push(1);
	qu.push(2);
	qu.push(3);
	qu.push(4);
	qu.push(5);

	while (!qu.empty())
	{
		cout << qu.back() << " ";
		qu.pop();
	}
	cout << endl;
}

结果:1 2 3 4 5

优先队列

只能检索最大堆元素,优先队列中位于顶部的元素

priorty_queue<int,vector<int>>一个天然的建堆,就是堆的思想。

向上调节和向下调节。

	template<class T, class Container>
	class priority_queue
	{
	public:
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
		T& top()
		{
			return _con.front();
		}
		void pop()
		{
			if (_con.size() == 0)
			{
				return;
			}
			std::swap(_con[0], _con[_con.size() - 1]);  //  将头(最大的数交换到尾)
			_con.pop_back();   // 删除尾元素
			//将交换上来的root下调(构建新大堆)  AdjustDown
			int parent = 0;
			int child = 1;
			while (child <= _con.size()-1)
			{
				if (child + 1 <= _con.size() - 1 && _con[child + 1] > _con[child])
				{
					child++;
				}
				if (_con[child] > _con[parent])
				{
					std::swap(_con[parent], _con[child]);
				}
				else
				{
					break;
				}
				parent = child;
				child = parent * 2 + 1;
			}
		}
		void push(const T& val)
		{
			int size = _con.size();
			_con.push_back(val);      // 增加一个空间
			int child = size;     // size变为了尾坐标
			int parent = (size - 1) / 2;
			while (parent >= 0)
			{

				if (child + 1 <=  _con.size() -1 && _con[child + 1] > _con[child])
				{
					child++;
				}
				if (_con[parent] <  _con[child])
				{
					std::swap(_con[parent], _con[child]);
				}
				//else          //  是没有break的
				//{
				//	break;
				//}
				parent--;
				child = parent * 2 + 1;
			}
		}
	private:
		Container _con;
	};
}

测试

void test4()
{
	priority_queue<int, vector<int>> pq;
	pq.push(1);
	pq.push(3);
	pq.push(98);
	pq.push(4);
	pq.push(33);
	pq.push(25);
	pq.push(46);
	pq.push(61);
	pq.push(13);
	cout << pq.top() << endl;


	pq.pop();
	cout << pq.top() << endl;

	pq.pop();
	cout << pq.top() << endl;

	pq.pop();
	cout << pq.top() << endl;

	pq.pop();
	cout << pq.top() << endl;

	pq.pop();
	cout << pq.top() << endl;

	pq.pop();
	cout << pq.top() << endl;
}

结果:
98
61
46
33
25
13
4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值