zoukankan      html  css  js  c++  java
  • 《数据结构与算法分析》学习笔记(四)——栈ADT

    一、栈ADT是what?

    1、定义

            栈,是限制插入和删除都只能在一个位置上进行的表。

    2、图示        

                                   

    3、栈的基本功能

    (1)是否为空

    (2)进栈

    (3)出栈

    (4)清空

    (5)取栈顶

    二、栈的链表实现

    #ifndef Exercise_Stack_h
    #define Exercise_Stack_h
    
    typedef struct Node *PrtToNode;
    typedef PrtToNode Stack;
    typedef int ElementType;
    
    
    struct Node
    {
        ElementType Element;
        PrtToNode Next;
    };
    
    
    bool IsEmpty(Stack S);
    
    Stack CreateStack();
    
    void MakeEmpty(Stack S);
    
    void Push(ElementType X,Stack S);
    
    void Pop(Stack S);
    
    ElementType Top(Stack S);
    
    #endif
    
    
    
    
    
    
    bool IsEmpty(Stack S)
    {
        return S->Next==nullptr;
    }
    
    
    Stack CreateStack()
    {
        Stack S;
        
        S = new struct Node;
        if(S==nullptr)
        {
            std::cout<<"Create Error!"<<std::endl;
            return nullptr;
        }
        
        S->Next=nullptr;
    
        return S;
    }
    
    void MakeEmpty(Stack S)
    {
        if(S==nullptr)
        {
            std::cout<<"not initStack Error!"<<std::endl;
            return ;
        }
        
        while (!IsEmpty(S))
        {
            Pop(S);
        }
        
    }
    
    
    void Push(ElementType X,Stack S)
    {
        PrtToNode Temp;
        
        Temp = new struct Node;
        if(Temp==nullptr)
        {
            std::cout<<"init Node Error!"<<std::endl;
            return;
        }
        
        Temp->Element=X;
        Temp->Next=S;
        S->Next=Temp;
    }
    
    
    void Pop(Stack S)
    {
        if(IsEmpty(S))
        {
            std::cout<<"Stack Empty!"<<std::endl;
            return;
        }
        auto temp = S->Next;
        S->Next=S->Next->Next;
        delete temp;
    }
    
    
    ElementType Top(Stack S)
    {
        if(IsEmpty(S))
        {
            std::cout<<"Stack Empty!"<<std::endl;
            return  0;
        }
        return S->Next->Element;
    }

    PS:优点:不用担心栈溢出的现象

           缺点:开辟内存和释放内存的时候貌似开销比较昂贵。

    三、栈的数组实现

    typedef int ElementType;
    const int MaxCapacity = 100;
    
    struct StackRecord
    {
        int Capacity;
        int TopOfStack;
        ElementType *Array;
    };
    
    typedef struct StackRecord *Stack;
    
    bool IsFull(Stack S);
    
    bool IsEmpty(Stack S);
    
    Stack CreateStack(int MaxElements);
    
    void DisposeStack(Stack S);
    
    void MakeEmpty(Stack S);
    
    void Push(ElementType X,Stack S);
    
    void Pop(Stack S);
    
    ElementType Top(Stack S);
    
    ElementType TopandPop(Stack S);
    
    
    
    
    
    Stack CreateStack(int MaxElements)
    {
        Stack S;
        
        S = new struct StackRecord;
        if(S==nullptr)
        {
            std::cout<<"Out of space!"<<std::endl;
            return nullptr;
        }
        
        S->Array = new ElementType(MaxElements);
        if(S->Array==nullptr)
        {
            std::cout<<"Out of space!"<<std::endl;
            return nullptr;
        }
        
        S->Capacity=MaxElements;
        S->TopOfStack=-1;
        
        MakeEmpty(S);
        
        return S;
        
    }
    
    void DisposeStack(Stack S)
    {
        if(S!=nullptr)
        {
            delete S->Array;
            delete S;
        }
    }
    
    
    bool IsEmpty(Stack S)
    {
        return S->TopOfStack==-1;
    }
    
    void MakeEmpty(Stack S)
    {
        S->TopOfStack=-1;
    }
    
    void Push(ElementType X,Stack S)
    {
        if(IsFull(S))
        {
            std::cout<<"Full Stack"<<std::endl;
            return;
        }
        S->Array[++S->Array[S->TopOfStack]]=X;
                 
    }
    
    ElementType Top(Stack S)
    {
        if(!IsEmpty(S))
        {
            return S->Array[S->TopOfStack];
        }
        
        std::cout<<"Empty Error"<<std::endl;
        return 0;
    }
    
    void Pop(Stack S)
    {
        if(IsEmpty(S))
        {
            std::cout<<"Empty Error"<<std::endl;
        }
        else{
            S->TopOfStack--;
        }
    }
    
    ElementType TopandPop(Stack S)
    {
        if(!IsEmpty(S))
        {
            return S->Array[S->TopOfStack--];
        }
        std::cout<<"Empty Error"<<std::endl;
        return 0;
    
    }
    
    bool IsFull(Stack S)
    {
        return S->Capacity==MaxCapacity;
    }

    优点:把不断开空间的时间省下来了;

    缺点:数组商都是有限的;

    四、应用

    (1)括号的匹配

    void test(string s)
    {
        auto stack = CreateStack(100);
        
        for(auto c: s)
        {
            if(c=='['||c=='{'||c=='(')
            {
                Push(c, stack);
            }
            else
            {
               if(c==']'||c=='}'||c==')')
               {
                   if(IsEmpty(stack))
                   {
                       cout<<"Error!"<<endl;
                   }
                   else
                   {
                      if(c==']')
                      {
                          auto temp = TopandPop(stack);
                          if(temp!='[')
                          {
                              cout<<"Error!"<<endl;
                          }
                      }
                       else if(c=='}')
                       {
                           auto temp = TopandPop(stack);
                           if(temp!='{')
                           {
                               cout<<"Error!"<<endl;
                           }
                       }
                       else if(c==')')
                       {
                           auto temp = TopandPop(stack);
                           if(temp!='(')
                           {
                               cout<<"Error!"<<endl;
                           }
                       }
                       else
                       {
                           cout<<"Scanf Error!"<<endl;
                       }
    
                   }
               }
               else
               {
                   cout<<"Scanf Error!"<<endl;
               }
            }
            
        }
        
        if(stack->TopOfStack==-1)
        {
            cout<<"RIGHT"<<endl;
        }
        else
        {
            cout<<"Error!"<<endl;
        }
        
    }

    (2)后缀表达式的计算。

    后缀表达式的优点就是完全不需要考虑什么优先级之类的,直接从左边算到右边就可以了,简直方便快捷,在这里我就默默的实现下,小白勿喷

    int calculate(string S)     //10以内的整数运算
    {
        
        auto stack = CreateStack(100);
        
        
        for(auto c:S)
        {
            switch (c)
            {
                case '+' :
                {
                    auto t1=TopandPop(stack);
                    auto t2=TopandPop(stack);
                    double t3=t1+t2;
                    
                    Push(t3, stack);
                }
                    
                    break;
                    case '-':
                {
                    auto t1=TopandPop(stack);
                    auto t2=TopandPop(stack);
                    double t3=t2-t1;
                    
                    Push(t3, stack);
                }
                    break;
                    case '*':
                {
                    auto t1=TopandPop(stack);
                    auto t2=TopandPop(stack);
                    double t3=t2*t1;
                    
                    Push(t3, stack);
                }
                    break;
                    case '/':
                {
                    auto t1=TopandPop(stack);
                    auto t2=TopandPop(stack);
                    double t3=t2/t1;
                    
                    Push(t3, stack);
                }
                    break;
                default:
                {
                    Push(c-'0', stack);
                }
                    break;
            }
        }
        
        
        return Top(stack);
        
    }

     3、中缀表达式转化成后缀表达式

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<vector>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    int pre(char a) //操作符优先级比较
    {
        if(a == '=' || a == '(')
            return 0;
        else if(a == '+' || a == '-')
            return 1;
        else if(a == '*' || a == '/')
            return 2;
        else
        {
            cout<<"Error!"<<endl;
            return 0;
        }
    }
    
    int main()
    {
        string str;
        stack<char> ope; //操作符
        vector<char> ans;//后缀表达式
        vector<char>::iterator start, end;
            getchar(); //清除输入垃圾
        
            while(!ope.empty()) //初始化
                ope.pop();
            ans.clear();
            ope.push('='); //结束标志
            cin>>str;
            auto len = str.length();
            for(int i = 0 ; i < len; ++i)
            {
                if(str[i] >= '0' && str[i] <= '9') //操作数直接存入ans
                    ans.push_back(str[i]);
                else if(str[i] == '(') //左括号入栈
                    ope.push(str[i]);
                else if(str[i] == ')') //右括号,将匹配的左括号内容存入ans,左括号出栈
                {
                    while (ope.top() != '(')
                    {
                        ans.push_back(ope.top());
                        ope.pop();
                    }
                    ope.pop(); //左括号出栈
                }
                else if(pre(str[i]) > pre(ope.top())) //优先级大于栈顶元素则入栈
                    ope.push(str[i]);
                else //小于栈顶元素
                {
                    while(pre(str[i]) <= pre(ope.top()))
                    {
                        ans.push_back(ope.top());
                        ope.pop();
                    }
                    ope.push(str[i]);
                }
            }
            while(ope.top() != '=') //其余操作符存入后缀表达式中
            {
                ans.push_back(ope.top());
                ope.pop();
            }
            for(start = ans.begin(), end = ans.end(); start < end; ++start)
                printf("%c", *start);
            printf("
    ");
        
        return 0;
    }
  • 相关阅读:
    判断开始时间不能小于结束时间
    angular1.0使用echarts点刷新再次调用echarts方法
    解决angular4.0打包后不能再继续打包
    html拼接+layer按钮
    angular.js+echarts
    nginx配置
    NET_Framework_4.0installer.rar
    IIS6.0开启gzip压缩
    IIS的应用程序池优化方法
    远程桌面连接电脑后键盘失灵解决
  • 原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/3917848.html
Copyright © 2011-2022 走看看