从入门到了解C++系列-----stack、queue、priority_queue

        本章将会讲解容器适配器的底层逻辑实现,是我学到的主流写法。当作是我学习理解的笔记。

基本上这个思维导图,就是所有相关的内容。

1.stack

         栈,先进后出,只有栈顶的元素也就是_con.back()。实现代码如下:

#pragma once
#include <iostream>
#include <vector>
#include <list>
#include<deque>

namespace djx
{
	template<class T, class Container = deque<T>>
	class stack
	{
	public:
		void push(T x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}
		size_t size()
		{
			return _con.size();
		}
		const T& top()//设计为栈顶元素
		{
			return _con.back();
		}
		bool empty()
		{
			return _con.empty();
		}
	private:
		Container _con;
	};
}

2. 队列

        先进先出,有队首、尾的数据之分。适配器就是去调用别的容器的内容。

#pragma once
#include <iostream>
#include <vector>
#include <list>
#include <deque> 
//queue 是一种适配器,直接使用其他容器的模板就可以
namespace djx
{
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		//队列具有:先进先出、队首,尾的值
		void push(const T& x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_front();
		}
		const T& back()
		{
			return _con.back();
		}
		const T& front()
		{
			return _con.front();
		}
		size_t size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
		
	private:
		Container _con;//就是去使用默认的 deque 的结构
	};
}

3.优先级队列

      本质上就是堆的实现。(由于库 swap 函数总是报错,所以我自己又定义了一个函数)

#pragma once
#include <iostream>
#include <vector>
#include <list>
#include <deque> 
//优先级队列在默认的时候,本质上就是一个大堆
//在打印输出的时候(默认)大的先输出
namespace djx
{
	
	template<class T>
	class less
	{
	public:
		bool operator()(const T& x1, const T& x2)
		{
			return x1 < x2;//如果是 x1 小于 x2 就是ture
		}
	};

	template<class T>
	class greater
	{
	public:
		bool operator()(const T& x1, const T& x2)
		{
			return x1 > x2;
		}
	};
	template<class T, class Container = vector<T>, class Comper = less<T>>
	class priority_queue
	{
	public:
		void swap(T& a, T& b)
		{
			T tmp = a; 
			a = b;
			b = tmp;
		}
		void push(const T x)
		{
			//进行插入操作的时候先建立一个大堆,放到最后面,然后需要使用向上调整算法进行排序
			_con.push_back(x);
			adjust_up(_con.size() - 1);
		}
		//void adjust_up(int n)
		//{
		//	int child = n;
		//	int parent = (n - 1) / 2;
		//	while (child > 0)
		//	{
		//		//之前的就一直是大堆,所以在放入的时候就是判断 孩子 与 父亲的大小
		//		if (_con[child] > _con[parent])
		//		{
		//			swap(_con[child], _con[parent]);
		//			child = parent;
		//			parent = (child - 1) / 2;
		//		}
		//		else break;
		//	}
		//}
		//对上面的进行优化,使用 less 函数
		void adjust_up(int n)
		{
			Comper _cmp;
			int child = n;
			int parent = (n - 1) / 2;
			while (child > 0)
			{
				//之前的就一直是大堆,所以在放入的时候就是判断 孩子 与 父亲的大小
				if(_cmp(_con[parent], _con[child]))
				//if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else break;
			}
		}
		void adjust_down(int n)
		{
			int parent = n;
			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				//找到左孩子与右孩子的最大值
				Comper _cmp;
				if (child + 1 < _con.size() && _cmp(_con[child], _con[child + 1]))
				//if (child + 1 < _con.size() && _con[child] < _con[child + 1])//还需要确保一定有右孩子
				{
					child++;
				}
				if(_cmp(_con[parent], _con[child]))
				//if (_con[child] > _con[parent])
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else break;
			}
		}
		void pop()
		{
			//首先先将第一个位置的值给交换下来
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			adjust_down(0);
		}
		int size()
		{
			return _con.size();
		}
		bool empty()
		{
			return _con.empty();
		}
		const T& top()
		{
			return _con[0];
		}
	private:
		Container _con;
	};
}

 结尾 

         以上是对于STL中适配器简单实现,如果是日常使用直接使用库函数即可。这是我的调试代码存放在了gitee之中Practice: 日常的练习。这个文章用于我的学习记录,如果是有其他的错误还请批评指正。如果对你有帮助还请给我点个赞👍👍👍。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值