链式栈

Link Stack

//栈的链式存储
//就是单链表; 受限的单链表, 一般不需要带头结点

#include<iostream>
#include<string>
using namespace std;

//链式栈中每个节点的定义
template<typename T>
struct StackNode
{
    T   data;                   //数据域
    StackNode<T>* next;         //指针域,指向下一个同类型节点     
};

//链式栈的定义
template<typename T>
class LinkStack
{
public:
    LinkStack();                        //构造函数
    ~LinkStack();                       //析构函数

public:
    bool Push(const T& e);              //入栈
    bool Pop(T& e);                     //出栈
    bool GetTop(T& e);                  //读取栈顶元素,但该元素没有出栈

    void DispList();                    //输出链式栈中的所有元素
    int ListLength();                   //获取链式栈的长度
    bool Empty();                       //判断栈是否为空

private:
    StackNode<T>*   m_top;              //栈顶指针
    int m_length;                       //链式栈当前场长度
};

template<typename T>
LinkStack<T>::LinkStack()
{
    m_top = nullptr;
    m_length = 0;
}

//入栈操作
template<typename T>
bool LinkStack<T>::Push(const T& e)
{
    StackNode<T> *node = new StackNode<T>;
    node->data = e;
    node->next = m_top;
    m_top = node;
    m_length++;
    return true;
}

//出栈,也就是删除栈顶数据
template<typename T>
bool LinkStack<T>::Pop(T& e)
{
    if(Empty() == true)
        return false;
    StackNode<T>* p_willdel = m_top;
    m_top = m_top->next;
    e = p_willdel->data;
    delete p_willdel;
    m_length--;
    return true;
}

//读取栈顶元素,但是该元素并没有出栈,而是依旧在栈中
template<typename T>
bool LinkStack<T>::GetTop(T& e)
{
    if(Empty() == true)
        return false;
    e = m_top->dat;
    return true;
}

//输出栈中的所有元素
template<typename T>
void LinkStack<T>::DispList()
{
    if(Empty() == true)
        return ;
    StackNode<T>* p = m_top;
    while(p != nullptr)
    {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}

//获取链式栈的长度
template<typename T>
int LinkStack<T>::ListLength()
{
    return m_length;
}

//判断是否为空
template<typename T>
bool LinkStack<T>::Empty()
{
    if(m_top == nullptr)
        return true;
    return false;
}

//析构函数
template<typename T>
LinkStack<T>::~LinkStack()
{
    StackNode<T> * temp = m_top;
    while(m_top)
    {
        m_top = m_top->next;
        delete temp;
        temp = m_top;
    
    }
}

int main()
{

    // LinkStack<int> myobj;
    // myobj.Push(12);
    // myobj.Push(24);
    // myobj.Push(48);
    // myobj.Push(100);
    // myobj.DispList();

    // int temp = 0;
    // myobj.Pop(temp);
    // myobj.DispList();



    cout << "-------------下面是括号匹配的例子-------------------" <<endl;
    bool ifMatchSucc = true;       //是否匹配成功的标志,先标记匹配成功
    LinkStack<char> matchobj;
    string strExp = "[({}){}]";
    for(size_t i = 0; i < strExp.size(); ++i)
    {
        if(strExp[i] == '(' ||    //左括号全部入栈
           strExp[i] == '[' ||
           strExp[i] == '{')
           {
                matchobj.Push(strExp[i]);
           }
        else
        {
            //当前是个又括号,则从栈顶去除一个左括号
            char tempchar;
            if(matchobj.Pop(tempchar) == false) // 从栈顶取出数据失败
            {
                ifMatchSucc = false;
                break;
            }

            //取得了栈顶的一个左括号,看一看是否匹配
            if((strExp[i] == ')' && tempchar == '(') ||
               (strExp[i] == ']' && tempchar == '[') ||
               (strExp[i] == '}' && tempchar == '{') )
               {
                continue;
               }

            else
            {
                ifMatchSucc = false;
                break;
            }
        }
    }//end for;
    //扫描完成,还要确定matchobj栈为空才可以
    if(ifMatchSucc == true && matchobj.Empty() == false)
    {
        ifMatchSucc = false;
    }

    if(ifMatchSucc == true)
    {
        cout << "\"" <<strExp << "\"格式合法,括号配对数量和顺序都正确" << endl;
    }
    else
    {
        cout << "\"" <<strExp << "\"格式非法,括号配对数量和顺序不正确" << endl;

    }
    return 0;
}

//栈存在的意义和引用举例
//a)保存临时数据,函数调用栈,栈帧
//b)利用栈来进行括号匹配
//c)计算表达式结果,利用栈把中缀表达式转换成后缀表达式(逆波兰表达式),然后再次利用栈对后缀表达式得到最终结果

 

posted @ 2022-07-25 16:29  huahuati  阅读(45)  评论(0)    收藏  举报