数据结构【栈、队列】相关代码(数据结构笔试、复测、Leecode、牛客)

基础介绍

  • 栈是一种只能在一端进行插入或删除操作的线性表。
  • 特点:先进后出
  • 分类:顺序栈和链栈

基础

【模板】栈

定义、进栈、出栈

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;
int st[N];
int top = -1;

int main()
{
    int n;
    cin>>n;
       
    while(n--)
    {
        string c;
        cin>>c;
        if(c == "push")
        {
            int x;
            cin>>x;
            st[++top] = x;
        }else if(c == "top"){
            if(top == -1)
                cout<<"error"<<endl;
            else{
                cout<<st[top]<<endl;
            }
        }else if(c == "pop"){
            if(top == -1)
                cout<<"error"<<endl;
            else{
                cout<<st[top--]<<endl;
            }
        }
    }
    return 0;
    
}

栈的压入、弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        stack<int> data; //构建栈
        int j = 0;
        for(int i = 0; i < pushV.size(); i++)
        {
            data.push(pushV[i]); //进栈
            while(data.size() > 0 && popV[j] == data.top())
            {
                data.pop();
                j++;
            }
        }
        return data.empty();
    }
};

有效括号序列

给出一个仅包含字符’(‘,’)‘,’{‘,’}‘,’[‘和’]',的字符串,判断给出的字符串是否是合法的括号序列

class Solution {
public:
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    bool isValid(string s) {
        // write code here
        stack<char> data;
        
        int n = s.length();
        if(n%2 != 0)
            return false;
        
        for(int i = 0; i<n; i++)
        {
            if(data.size() == 0)
                data.push(s[i]);
            else{
                if(data.top() == '(' && s[i] == ')') 
                   data.pop();
                else if(data.top() == '[' && s[i] == ']') 
                   data.pop();
                else if(data.top() == '{' && s[i] == '}') 
                   data.pop();
                else 
                    data.push(s[i]);
            }
            
        }
        if(data.empty())
            return true;
        else
            return false;
        
    }
};

逆波兰表达式求值

给定一个逆波兰表达式,求表达式的值。

逆波兰表达式和日常书写的表达式区别是符号会后置。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param tokens string字符串vector 
     * @return int整型
     */
    int evalRPN(vector<string>& tokens) {
        // write code here
        stack<int> data;
        for(int i = 0; i<tokens.size(); i++)
        {
            if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/"){
                
                int t = atoi(tokens[i].c_str());//string-->int
                data.push(t);
            }
            else{
                int num = data.top();
                data.pop();
                if(tokens[i] == "+")
                    data.top() += num;
                else if(tokens[i] == "-"){
                    data.top() -= num;
                }else if(tokens[i] == "*"){
                    data.top() *= num;
                }else if(tokens[i] == "/"){
                    data.top() /= num;
                }
            }
        }
        return data.top();
    }
};

点击消除

牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string data;
    cin>>data;
    stack<char> xc1;
    //消除
    for(auto& i: data)
    {
        if(!xc1.empty() && xc1.top() == i){
            xc1.pop();
        }else
            xc1.push(i);  
    }
    
    //读取
    stack<char> xc2;
    while(!xc1.empty())
    {
        xc2.push(xc1.top());
        xc1.pop();
    }
    
    if(xc2.empty())
    {
        cout<<0<<endl;
        return 0;
    }
    
    //输出
    while(!xc2.empty())
    {
        cout<<xc2.top();
        xc2.pop();
        
    }
    return 0;
}

表达式求解

请写一个整数计算器,支持加减乘三种运算和括号。
空间复杂度: O(n),时间复杂度 O(n)

两个栈、一个存放运算符、一个存放数值

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回表达式的值
     * @param s string字符串 待计算的表达式
     * @return int整型
     */
    int solve(string s) {
        // write code here
        stack<int> num;//存放数值
        stack<char> ops;//存放运算符
        int sum = 0;//初始化计算值
        for(int i=0; i<s.size(); i++)
        {
            if(s[i]>='0' && s[i]<='9')
                sum = sum*10 +(s[i] - '0');//大于10的数值
            else
            {
                if(sum!=0)
                {
                    num.push(sum);//将数值入栈
                    sum = 0;
                }
                if(ops.empty() || ops.top() == '(' || s[i] == '(')
                    ops.push(s[i]);
                else{
                    if(s[i] == ')'){
                        while(ops.top() != '('){
                            int x = num.top();
                            num.pop();
                            int y = num.top();
                            num.pop();
                            if(ops.top() == '+')
                                num.push(x+y);
                            else if(ops.top() == '-')
                                num.push(y-x);
                            else if(ops.top() == '*')
                                num.push(x*y);
                            ops.pop();
                        }
                        ops.pop();
                    }else{
                        while(!ops.empty() && judge(s[i], ops.top()) == false)
                        {
                            int x = num.top();
                            num.pop();
                            int y = num.top();
                            num.pop();
                            if(ops.top() == '+')
                                num.push(x+y);
                            else if(ops.top() == '-')
                                num.push(y-x);
                            else if(ops.top() == '*')
                                num.push(x*y);
                            ops.pop();
                        }
                        ops.push(s[i]);
                    }
                }           
                    
            }
        }
            
       if(sum!=0)
       num.push(sum);
       while(!ops.empty())
       {
           int x = num.top();
           num.pop();
           int y = num.top();
           num.pop();
           if(ops.top() == '+')
               num.push(x+y);
           else if(ops.top() == '-')
               num.push(y-x);
           else if(ops.top() == '*')
               num.push(x*y);
           ops.pop();
       }
        return num.top();
    }
    
    bool judge(char c1, char c2)
    {
        if(c1 == '(')
            return true;
        else if(c1 == ')')
            return false;
        else if(c2 == '(')
            return true;
        else if((c1 == '*' || c1 == '/') && (c2 == '+' || c2=='-') )
            return true;
        else
            return false;
    }
};

进阶

队列

基础

【模板】队列

#include <bits/stdc++.h>
using namespace std;

const int maxSize = 1e5 + 5;

int main()
{
    //构建队列
    int data[maxSize];
    int front = 0; //队头
    int rear = 0; //队尾
    
    int n;
    cin>>n;
    
    while(n--)
    {
        string c;
        cin>>c;
        if(c =="push")
        {
            int x;
            cin>>x;
            data[rear] = x;
            rear = (rear+1) % maxSize;
        }else if(c == "pop")
        {
            if(front == rear)
                cout<<"error"<<endl;
            else{
                cout<<data[front]<<endl;     
                front = (front+1) % maxSize;
            }
        }else if(c == "front")
        {
             if(front == rear)
                cout<<"error"<<endl;
            else
                cout<<data[front]<<endl;
        }
    }
    return 0;
}

【模板】循环队列

#include <bits/stdc++.h>
using namespace std;



int main()
{
    //构建队列
    int n;
    cin>>n;
    n = n+1;//多一个空间
    int data[n];
    int front = 0; //队头
    int rear = 0; //队尾
    
    int q;
    cin>>q;
    
    while(q--)
    {
        string c;
        cin>>c;
        if(c =="push")
        {
            int x;
            cin>>x;
            if((rear+1)%n == front)
                cout<<"full"<<endl;
            else{
                data[rear] = x;
                rear = (rear+1) % n;
            }
        }else if(c == "pop")
        {
            if(front == rear)
                cout<<"empty"<<endl;
            else{
                cout<<data[front]<<endl;     
                front = (front+1) % n;
            }
        }else if(c == "front")
        {
             if(front == rear)
                cout<<"empty"<<endl;
            else
                cout<<data[front]<<endl;
        }
    }
    return 0;
}

进阶

栈和队列

简单

用两个栈实现队列

描述

用两个栈来实现一个队列,使用n个元素来完成 n 次在队列尾部插入整数(push)和n次在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。
class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        
        int t = 0;
        if(stack2.size() == 0){
            while(stack1.size() > 0){
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        t = stack2.top();
        stack2.pop();     
        
        return t; 
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值