stack和queue详解

一、stack

stack是一种先进后出的的数据结构(FILO),它只有一个出口点,同时也是进口点,stack它允许新增元素,移除元素,取得最顶端元素 ,但是除了最顶端之外没有任何方法取得最顶端元素,换言之,stack不支持遍历行为。


在c++库里面,stack的底部结构是deque,deque是双端开口的数据结构,stack是将deque作为底部结构,并封装了其头端开口形成stack。
因为stack是以底部容器完成其所有功能,而这种具有“修改容器接口而形成另一种风格者,成为adapter(适配器),在STL不称为container(容器),被归类为container adapter(容器适配器)”

在这里插入图片描述

二、stack模拟实现

//因为stack是靠着其它2容器实现成功的,所以它实现提别简单

namespace bit
{
	template<class T, class container = vector<T>>
	class stack
	{
		container _con;
	public:
		void push(T x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}

		bool empty()
		{
			return _con.empty();
		}

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

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

	};

vector和list在库里面都有相关函数,比如尾插,尾删,empty,size,等等。
那有疑问了,为什么这里不需要写构造函数和析构函数?

原因是,编译器会自动调用list或者vector的构造函数和析构函数,所以这里就不用写了

测试:

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

using namespace std;

namespace bit
{
	template<class T, class container = vector<T>>
	class stack
	{
		container _con;
	public:
		void push(T x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_back();
		}

		bool empty()
		{
			return _con.empty();
		}

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

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

	};

	void test()
	{
		stack<int> q;
		q.push(1);
		q.push(2);
		q.push(7);
		q.push(0);
		q.push(5);
		while (!q.empty())
		{
			cout << q.top() << " ";
			q.pop();
		}	
	}

}

int main()
{
	bit::test();
	return 0;
}

在这里插入图片描述
在这里插入图片描述

在测试的时候,我在初始化的时候写了一个超级大的错误,
初始化的时候我写成了stack<vector< int>> q ,这样写的话会发生如下错误
在这里插入图片描述
正确初始化应该是 stack< int> q,这个等价于stack< int,<vector < int >> q
因为有模板的缘故,可以帮助我们省掉后一部分。
要是底层想用list实现, 初始化就得是 stack< int,<list< int >> q

三、queue(队列)

queue是一种先进先出的数据结构,(FIFO),它有两个出口。queue允许新增元素,移除元素,从最低端加入元素,取得最顶端元素,但除了从最低端加入元素,最顶端取出元素之外,它没有任何方法访问其他元素,换言之,queue不允许有其他的遍历行为
在这里插入图片描述
在库里面实现queue是将deque作为底部结构,并封闭其底端出口和前端入口,queue没有迭代器,只有顶端元素才能被访问,也不支持遍历访问

四、queue的模拟实现

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

using namespace std;

namespace bit
{
	template<class T,class container = list<int>>
	class queue
	{
		container _con;

	public:
		void push(T x)
		{
			_con.push_back(x);
		}
		void pop()
		{
			_con.pop_front();
		}

		bool empty()
		{
			return _con.empty();
		}

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

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

	void test1()
	{
		queue<int> q;
		q.push(1);
		q.push(2);
		q.push(7);
		q.push(0);
		q.push(5);
		while (!q.empty())
		{
			cout << q.front() << " ";
			q.pop();
		}
	}


}


int main()
{
	bit::test1();
	return 0;
}

在这里插入图片描述
这里为什么没有构造函数和析构函数理由与stack一样

五、经典例题

在这里插入图片描述
思路:

用一个int levelSize变量记录每一层的个数,用一个队列记录每一层的数据,在将每一层的数据加进vector里面,当这一层数据全部记录后,将vector里面的数据加进vector<vector>里面
在这里插入图片描述


class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        vector<vector<int>> vv;//需要返回的vector
        int levelSize = 0;//记录每一层元素的个数
        queue<TreeNode*> q;
        if(root)
        {
            levelSize = 1;
            q.push(root);
            
        }
        while(!q.empty())
        {
            vector<int> v;
            for(int i = 0;i < levelSize;i++)
            {
                TreeNode* front = q.front();
                v.push_back(front->val);
                q.pop();
                if(front->left)
                {
                    q.push(front->left);
                }
                if(front->right)
                {
                    q.push(front->right);
                }
            }//该for结束后,v里面记录该一层的所有数据,q里面是下一层的所有数据
            vv.push_back(v);
            levelSize = q.size();//更新levelSize,使得levelSize的值变为下一层数据的个数
        }
        return vv;
        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值