【STL】序列式容器--stack和queue

【STL】常用容器总结,带有复习性质的学习更有效率;


【栈和队列】

栈和队列相关的问题在面试中真的是被问的不要不要的,下面我先从栈和队列的数据结构开始复习,最后做几道栈和队列的相关面试题作为巩固;

【栈】: 一种先进后出的结构,在操作系统中应用广泛;在STL中的栈容器,底层默认是deque作为数据结构(queue也是一样),但是由于双端队列用的比较少,而且比较复杂,没有过多研究,同样list和vector都可以作为栈的底层数据结构;

栈和队列都不允许被遍历,所以都没有迭代器,栈最常见的操作就是pop和push,操作的对象都是栈顶元素;

【队列】:一种先进先出的数据结构,底层数据结构和栈一致,同时也不允许遍历,所以没有迭代器;同时队列提供队头队尾的插入和删除操作,但是可以提供的元素只有队头(front);

上面就是栈和队列的结构总结,下面就做一些具体的例子,来更深刻的了解一下;

【两个栈实现一个队列】

#include<iostream>
#include<stack>

using namespace std;

//两个栈实现一个队列(先进先出的特性)

template<typename T>
class Queue
{
public:
    void Push(const T& value)
    {
        s1.push(value);
    }

    T Pop()
    {
        if(s1.empty() && s2.empty())
            return T();

        if(s2.empty())
        {
            while(!s1.empty())
            {
                s2.push(s1.top());
                s1.pop();
            }
        }
        s2.pop();
    }

    T Front()
    {
        if(s1.empty() && s2.empty())
        {
            return T();
        }
        else
        {
            if(!s2.empty())
                return s2.top();
            else
            {
                while(!s1.empty())
                {
                    s2.push(s1.top());
                    s1.pop();
                }
                return s2.top();
            }
        }
    }
private:
    stack<T> s1;
    stack<T> s2;
};

int main()
{
    Queue<int> q;
    for(int i = 0; i < 5; i++)
    {
        q.Push(i);
    }

    cout<<q.Front()<<endl;
    q.Pop();
    cout<<q.Front()<<endl;
    system("pause");
    return 0;
}

【两个队列实现一个栈】

//两个队列实现一个栈(后进先出特性)
#include<iostream>
#include<queue>

using namespace std;

template<typename T>
class Stack
{
public:
    void Push(const T& val)
    {
        if(q1.empty() && !q2.empty())
        {
            q2.push(val);
        }
        else
        {
            q1.push(val);
        }
    }

    void Pop()
    {
        if(q1.empty() && !q2.empty())
        {
            while(q2.size() > 1)
            {
                q1.push(q2.front());
                q2.pop();
            }
            q2.pop();
        }
        else if(q2.empty() && !q1.empty())
        {
            while(q1.size() > 1)
            {
                q2.push(q1.front());
                q1.pop();
            }
            q1.pop();
        }
        else
        {
            return;
        }
    }

    T top()
    {
        if(q1.empty() && q2.empty())
            return T();
        if(q1.empty())
            return q2.back();
        else
            return q1.back();
    }
private:
    queue<T> q1;
    queue<T> q2;
};

int main()
{
    Stack<int> s;

    for(int i = 0; i < 5; ++i)
    {
        s.Push(i);
    }

    cout<<s.top()<<endl;
    s.Pop();
    cout<<s.top()<<endl;
    system("pause");
    return 0;
}

【判断出入栈的合法性】

#include<iostream>
#include<vector>
#include<stack>

using namespace std;

//判断出栈的合法性,没有重复元素
template<typename T>
bool JudgeStack(vector<T> input, vector<T> output)
{
    stack<T> s;
    int i = 0;
    int j = 0;

    while(j < output.size())
    {
        while(s.empty() || s.top() != output[j])
        {
            if(i == input.size())
            return false;
            if(i == input.size())
                break;
            s.push(input[i++]);
        }
        if(s.top() == output[j])
            s.pop();
        j++;
    }

    if(s.empty())
        return true;
    return false;
}

int main()
{
    int arr[] = {1,2,3,6,5};
    vector<int> v1(arr, arr+5);
    int str[] = {3,2,5,1,6};
    vector<int> v2(str,str+5);

    cout<<JudgeStack(v1,v2)<<endl;

    return 0;
}

【O(1)的栈】:实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)

#include<iostream>
#include<stack>

using namespace std;

template<typename T>
class Stack
{
public:
    void Push(const T& val)
    {
        if(s.empty() || val < s.top())
        {
            s.push(val);
            s.push(val);
        }
        else
        {
            T tmp = s.top();
            s.push(val);
            s.push(tmp);
        }
    }

    void Pop()
    {
        s.pop();
        s.pop();
    }

    T Min()
    {
        if(!s.empty())
            return s.top();
    }
private:
    stack<T> s;
};

int main()
{
    Stack<int> s;
    s.Push(4);
    s.Push(3);
    s.Push(2);
    s.Push(5);
    cout<<s.Min()<<endl;
    s.Pop();
    cout<<s.Min()<<endl;
    return 0;
}

以前写的博客链接:
面试题之两个队列实现一个栈
面试题之用两个栈实现一个队列
判断出入栈的合法性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值