栈的面试题总结

1.不用辅助空间实现栈的逆序(利用函数的递归)
例如栈中元素1 2 3 4,逆序后栈中元素为4 3 2 1

int GetLastNumOfStack(stack<int>& s)// 得到栈顶的元素
{
    int result = s.top();//取栈顶元素
    s.pop();//出栈
    if(s.empty()==true)
        return result;//若是栈顶元素,则将该元素返回到上级函数
    int last = GetLastNumOfStack(s);//接受返回的栈顶元素
    s.push(result);//并将此时出栈的元素压入栈中(除栈顶元素外)
    return last;//将栈顶元素返回到上级函数
}
void ReseriveStack(stack<int>& s)//利用递归实现栈元素逆序
{
    if(s.empty()==true)
        return;
    int i = GetLastNumOfStack(s);//得到第一个栈底元素
    ReseriveStack(s);//函数递归
    s.push(i);//元素压栈
}

测试代码

int main()
{
    stack<int> s;
    s.push(1);
    s.push(2);
    s.push(3);
    ReseriveStack(s);
    return 0;
}

2.得到GetMin功能的栈

  • 方法一:
#include<stdio.h>
#include<stack>
#include<iostream>
using namespace std;
#include<stack>

template<class T>
class Stack
{
public:
    Stack()
    {}

    void Push(const T& data)
    {
        StackData.push(data);
        if(StackMin.empty() || StackMin.top() > data)
            StackMin.push(data);
        else
            StackMin.push(StackMin.top());//StackData的值和StackMin元素的个数相同
    }

    void Pop()
    {
        if(StackData.empty())
            return;
        StackData.pop();
        StackMin.pop();
    }

    T GetMin()
    {
        return StackMin.top();
    }

private:
    stack<T> StackData;
    stack<T> StackMin;
};
  • 方法二:
#include<stack>

template<class T>
class Stack
{
public:
    Stack()
    {}

    void Push(const T& data)
    {
        StackData.push(data);
        if(StackMin.empty() || StackMin.top() > data)
            StackMin.push(data);
    }

    void Pop()
    {
        if(StackData.empty())
            return;
        int value = StackData.top();
        StackData.pop();
        if(value == StackMin.top())
            StackMin.pop();
    }

    T GetMin()
    {
        return StackMin.top();
    }

private:
    stack<T> StackData;
    stack<T> StackMin;
};

测试代码:

void funtest()
{
    Stack<int> s;
    s.Push(4);
    s.Push(1);
    s.Push(3);
    s.Push(2);
    s.Push(5);

    s.Pop();

    int ret = s.GetMin();
}

int main()
{
    funtest();
    getchar();
    return 0;
}

两种方法的比较:
两种方法的时间复杂度都相同,都为O(1),且空间复杂度都为O(N);区别是:方法一中StackData入栈的时候要浪费空间,但是弹出的时候节省时间,方法二中StackData入栈的时候要节省空间,但弹出时浪费时间。

3.由两个栈实现一个队列

template<class T>
class Queue
{
public:
    Queue()
    {}

    void Push(const T& value)
    {
        StackPush.push(value);
    }

    void Pop()
    {
        if(StackPop.empty() && StackPush.empty())
            return;
        if(StackPop.empty())
        {
            while(!StackPush.empty())
            {
                int num = StackPush.top();
                StackPop.push(num);
                StackPush.pop();
            }
        }
        StackPop.pop();
    }

private:
    stack<int> StackPush;
    stack<int> StackPop;
};

测试代码:

int main()
{
    Queue<int> q;
    q.Push(1);
    q.Push(2);
    q.Push(3);
    q.Push(4);

    q.Pop();

    getchar();
    return 0;
}

4.用一个栈来实现另一个栈的排序,要求栈由栈顶到栈底从大到小

void SortStackByStack(stack<int>& stackData)
{
    //由题意知,stackData由栈顶到栈底从大到小排序,则help由栈顶到栈底从小到大排序
    stack<int> help;

    if(stackData.empty())
        return;
    while(!stackData.empty())
    {
        int value = stackData.top();
        stackData.pop();
        if(help.empty() || value <= help.top())
            help.push(value);
        if(value > help.top())
        {
            while(!help.empty() && value > help.top())
            {
                int num = help.top();
                help.pop();
                stackData.push(num);
            }
            stackData.push(value);
        }
    }
    while(!help.empty())
    {
        int ret = help.top();
        help.pop();
        stackData.push(ret);
    }
}

测试代码:

void funtest()
{
    stack<int> s;
    s.push(6);
    s.push(5);
    s.push(4);
    s.push(3);
    s.push(2);
    s.push(1);

    SortStackByStack(s);
}

int main()
{
    funtest();
    getchar();
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值