【C++之容器适配器】栈和队列模拟实现

前言

前面我们学习的都是C++标准模板库中的一些容器,今天我们要学习几个容器适配器,容器适配器的底层原理是通过适配另一个容器的功能来完成当前容器功能的实现,今天学习的栈和队列是通过deque来适配的,下面我们详细讲解stack和queue还有priority_queue的模拟实现

一、栈(stack)

1. 基本代码结构

在这里插入图片描述

2. 简介

在这里插入图片描述

3. 成员类型

在这里插入图片描述

4. 成员函数

1. 构造函数

在这里插入图片描述
栈的底层是使用deque来进行适配的,deque是一个自定义类型的成员,所以栈自身不需要实现默认构造函数,编译器生成的默认构造函数会去调用deque的默认构造函数完成初始化。

2. empty()

在这里插入图片描述

这个函数的功能是判断栈是否为空,如果为空则返回true,如果不为空,则返false。同样的道理,stack的底层是适配了一个deque,所以直接调用deque的empty()完成判断即可。

  • 代码:
		bool empty() const
		{
			return _con.empty();
		}
3. size()

在这里插入图片描述
这个函数的功能是求栈中的元素个数。同样的道理,stack的底层是适配了一个deque,所以直接调用deque的size()完成判断即可。

  • 代码:
		size_t size() const
		{
			return _com.size();
		}
4. top()

在这里插入图片描述
这个函数的功能是求栈的栈顶元素。同样的道理,stack的底层是适配了一个deque,所以直接调用deque的back()完成判断即可。

  • 代码:
		const T& top() const
		{
			return _con.back();
		}

		T& top()
		{
			return _con.back();
		}
5. push()

在这里插入图片描述
这个函数的功能是将元素入栈。同样的道理,stack的底层是适配了一个deque,所以直接调用deque的push_back()完成判断即可。

  • 代码:
		void push(const T& val)
		{
			_con.push_back(val);
		}
6.pop()

在这里插入图片描述
这个函数的功能是将元素出栈。同样的道理,stack的底层是适配了一个deque,所以直接调用deque的pop_back()完成判断即可。

  • 代码:
void pop()
		{
			_con.pop_back();
		}
7. 综合测试实现的stack的所有函数接口
  • 代码:
void test_stack()
{
	hjt::stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	st.push(4);
	st.push(5);

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

}

int main()
{
	test_stack();
	return 0;
}

运行结果:
在这里插入图片描述

二、队列(queue)

1. 基本代码结构

namespace hjt
{
	template <class T,class Container = deque<T>>
	class queue
	{
	public:
		// 成员函数

	private:
		Container _con;
	};
}

2. 队列的简介

在这里插入图片描述

3. 成员类型

在这里插入图片描述

4. 成员函数

1. 构造函数

在这里插入图片描述
队列的底层是使用deque来进行适配的,deque是一个自定义类型的成员,所以队列自身不需要实现默认构造函数,编译器生成的默认构造函数会去调用deque的默认构造函数完成初始化。

2. empty()

在这里插入图片描述

这个函数的功能是判断队列是否为空,如果为空则返回true,如果不为空,则返false。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的empty()完成判断即可。

  • 代码:
		bool empty() const
		{
			return _con.empty();
		}
3. size()

在这里插入图片描述
这个函数的功能是求队列中的元素个数。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的size()完成判断即可。

  • 代码:
		size_t size() const
		{
			return _con.size();
		}
4. front()

在这里插入图片描述
这个函数的功能是求队列的队头元素。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的front()完成判断即可。

  • 代码:
		const T& front() const
		{
			return _con.front();
		}

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

在这里插入图片描述

这个函数的功能是求队列的队尾元素。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的back()完成即可。

  • 代码:
		const T& back() const
		{
			return _con.back();
		}

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

在这里插入图片描述
这个函数的功能是将元素入队。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的push_back()完成即可。

  • 代码:
		void push(const T& val)
		{
			_con.push_back(val);
		}
7. pop()

在这里插入图片描述
这个函数的功能是将元素出队。同样的道理,queue的底层是适配了一个deque,所以直接调用deque的pop_front()完成即可。

  • 代码:
		void pop()
		{
			_con.pop_front();
		}
8. 综合测试实现的queue的所有函数接口
  • 代码:
void test_queue()
{
	hjt::queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);
	q.push(6);

	while (!q.empty())
	{
		cout << q.front() << " ";
		q.pop();
	}
	cout << endl;

}
  • 运行结果:
    在这里插入图片描述

三、优先级队列(priority_queue)

1. 基本代码结构

// 实现优先级队列
	template <class T,class Container = vector<T>>
	class priority_queue
	{
	public:
		// 成员函数

	private:
		Container _con;
	};

2. 简介

在这里插入图片描述

3. 成员类型

在这里插入图片描述

4. 成员函数

1. 构造函数

在这里插入图片描述
优先级队列的底层是使用vector来进行适配的,vector是一个自定义类型的成员,所以优先级队列自身不需要实现默认构造函数,编译器生成的默认构造函数会去调用vector的默认构造函数完成初始化。

2. empty()

在这里插入图片描述
这个函数的功能是判断优先级队列是否为空,如果为空则返回true,如果不为空,则返false。同样的道理,priority_queue的底层是适配了一个vector,所以直接调用vector的empty()完成判断即可。

  • 代码:
bool empty() const
		{
			return _con.empty();
		}
3. size()

在这里插入图片描述
这个函数的功能是求优先级队列中元素个数,同样的道理,priority_queue的底层是适配了一个vector,所以直接调用vector的empty()完成判断即可。

  • 代码:
	size_t size() const
		{
			return _con.size();
		}
4. top()

在这里插入图片描述
这个函数的功能是求优先级队列中队顶元素,队顶元素是第一个元素,所以返回_con中的第一个元素即可。

  • 代码:
const T& top() const
		{
			return _con[0];
		}
5. push()

在这里插入图片描述
这个函数的功能是将数据插入priority_queue中,并且要保证插入数据之后仍然满足堆的性质,所以还需要实现一个向上调整算法

  • 代码:
void push(const T& val)
		{
			_con.push_back(val);
			AjustUp(_con.size() - 1);
		}

		void AjustUp(int child)
		{
			int parent = (child - 1) / 2;
			while (child > 0)
			{
				if (_con[parent] < _con[child])
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
6. pop()

在这里插入图片描述
这个函数的功能是删除priority_queue中的队顶元素,并且要保证插入数据之后仍然满足堆的性质,所以还需要实现一个向下调整算法

		void pop()
		{
			assert(!_con.empty());
			swap(_con[0], _con[_con.size() - 1]);
			_con.pop_back();
			AjustDown(0);
		}

		void AjustDown(int parent)
		{
			int child = parent * 2 + 1;
			while (child < _con.size())
			{
				if(child + 1 < _con.size() && _con[child] < _con[child + 1])
				{
					child++;
				}
				if (_con[parent] < _con[child])
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}
				
			}
		}
7. 综合测试实现的priority_queue的所有函数接口
  • 代码
void test_priority_queue()
{
	hjt::priority_queue<int> pq;
	pq.push(1);
	pq.push(2);
	pq.push(3);
	pq.push(4);
	pq.push(5);
	pq.push(6);

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

	hjt::priority_queue<int> pq1;
	pq1.push(3);
	pq1.push(1);
	pq1.push(2);
	pq1.push(5);
	pq1.push(6);
	pq1.push(7);
	cout << "pq1:" << endl;
	while (!pq1.empty())
	{
		cout << pq1.top() << " ";
		pq1.pop();
	}
	cout << endl;


}
  • 运行结果:
    在这里插入图片描述
  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值