3.栈与队列,c++模板类

本文探讨了栈(Stack)和队列(Queue)的数据结构实现,包括顺序表和链表版本,并展示了它们在括号匹配、表达式转换和图遍历中的实际应用。同时,深入解析了中缀表达式到后缀表达式的转换过程和后缀表达式的求值算法。
摘要由CSDN通过智能技术生成

栈:

Stack.h
#ifndef _STACK_H_
#define _STACK_H_

#define MaxSize 100

//顺序表实现
template<class T>
class SStack
{
public:
    SStack();
    ~SStack();

public:
    T pop();
    T top();
    int size();
    bool push(const T x);
    bool isEmpty();
    bool isFull();
    void clear();

private:
    T data[MaxSize];
    int Top;
};

//链表实现

template<class T>
class LSNode
{
public:
    LSNode():next_L(NULL){};
    LSNode(const T x, LSNode<T> *ptr = NULL)
    {
        data = x;
        next_L = ptr;
    }

public:
    T data;
    LSNode<T> *next_L;
};

template<class T>
class LStack : public LSNode<T>
{
public:
    LStack();
    ~LStack();

public:
    LSNode<T> *setPos();
    T pop();
    T top();
    int size();
    bool push(const T x);
    bool isEmpty();
    void clear();    

private:
    LSNode<T> *head, *Top;
};

#endif //_STACK_H_
Stack.cpp
#include "Stack.h"
#include <iostream>
using namespace std;

template<class T>
SStack<T>::SStack()
{
    Top = -1;
}

template<class T>
SStack<T>::~SStack()
{
    Top = -1;
}

template<class T>
T SStack<T>::pop()
{
    if(Top == -1)
    {
        cout << "Stack is empty return -1" << endl;
        return -1;
    }
    int idx = Top;
    Top --;
    return data[idx];
}

template<class T>
bool SStack<T>::push(const T x)
{
    if(Top == MaxSize-1)
    {
        cout << "Stack is full" << endl;
        return false;
    }
    data[++ Top] = x;
    return true;
}

template<class T>
bool SStack<T>::isEmpty()
{
    if(Top == -1)
        return true;
    return false;
}

template<class T>
void SStack<T>::clear()
{
    Top = -1;
}

template<class T>
T SStack<T>::top()
{
    return data[Top];
}

template<class T>
bool SStack<T>::isFull()
{
    if(Top == MaxSize-1)
        return true;
    return false;
}

template<class T>
int SStack<T>::size()
{
    return Top+1;
}

/*
                       .::::.
                     .::::::::.
                    :::::::::::  FUCK YOU
                ..:::::::::::'
              '::::::::::::'
                .::::::::::
           '::::::::::::::..
                ..::::::::::::.
              ``::::::::::::::::
               ::::``:::::::::'        .:::.
              ::::'   ':::::'       .::::::::.
            .::::'      ::::     .:::::::'::::.
           .:::'       :::::  .:::::::::' ':::::.
          .::'        :::::.:::::::::'      ':::::.
         .::'         ::::::::::::::'         ``::::.
     ...:::           ::::::::::::'              ``::.
    ````':.          ':::::::::'                  ::::..
                       '.:::::'                    ':'````..
*/

template<class T>
LSNode<T>* LStack<T>::setPos()
{
    LSNode<T> *p = head;
    if(head == Top)
    {
        return NULL;
    }
    while(p->next_L != Top)
    {
        p = p->next_L;
    }
    return p;
}

template<class T>
LStack<T>::LStack()
{
    head = new LSNode<T>(0, NULL);
    Top = head;
}


template<class T>
LStack<T>::~LStack()
{
    LSNode<T> *cur = head;
    while(cur != NULL)
    {
        LSNode<T> *del = cur;
        cur = cur->next_L;
        delete del;
    }
    head = NULL;
    Top = NULL;
}

template<class T>
void LStack<T>::clear()
{
    while(head != NULL)
    {
        LSNode<T> *p = head;
        head = head->next_L;
        delete p;
    }
    head = new LSNode<T>(0, NULL);
    Top = head;
}

template<class T>
T LStack<T>::pop()
{
    if(Top == head)
    {
        cout << "Stack is empty" << endl;
        return -1;
    }
    T x = Top->data;
    LSNode<T> *p = setPos();
    p->next_L = NULL;
    delete Top;
    Top = p;
    return x;
}

template<class T>
bool LStack<T>::push(const T x)
{
    LSNode<T> *p = new LSNode<T>(x, NULL);
    Top->next_L = p;
    Top = p;
    return true;
}

template<class T>
bool LStack<T>::isEmpty()
{
    if(Top == head)
        return true;
    return false;
}

template<class T>
T LStack<T>::top()
{
    if(Top == head)
        return -1;
    return Top->data;
}

template<class T>
int LStack<T>::size()
{
    LSNode<T> *p = head->next_L;
    int cnt = 0;
    while(p != NULL)
    {
        cnt ++;
        p = p->next_L;
    }
    return cnt;
}

队列

Dueue.h
#ifndef _QUEUE_H_
#define _QUEUE_H_
//待完善
#define MaxSize 100

//顺序表
template<class T>
class SQueue
{
public:
    SQueue();
    ~SQueue();

public:
    T front();
    T pop();
    int size();
    void clear();
    bool push(const T x);
    bool isEmpty();

private:
    T data[MaxSize];
    int head, tail;
};


//链式

template<class T>
class LNode
{
public:
    LNode():next_L(NULL){};
    LNode(const T x, LNode<T> *ptr = NULL)
    {
        data = x;
        next_L = ptr;
    }

public:
    T data;
    LNode<T> *next_L;
};

template<class T>
class LQueue : public LNode<T>
{
public:
    LQueue();
    ~LQueue();

public:
    T pop();
    T front();
    int size();
    void clear();
    bool push(const T x);
    bool isEmpty();


private:
    LNode<T> *head, *tail;
};


// 双端队列

template<class T>
class DueNode
{
public:
    DueNode():next_L(NULL){};
    DueNode(T d, DueNode<T> *ptr = NULL)
    {
        data = d;
        next_L = ptr;
    }

public:
    T data;
    DueNode<T> *next_L;
};

template<class T>
class Dueue
{
public:
    Dueue();
    ~Dueue();

public:
    
    T pop_back();
    T pop_front();
    T front();
    T back();
    int size();
    void clear();
    bool isEmpty();
    bool push_back(const T x);
    bool push_front(const T x);
    void Print();

private:
    DueNode<T> *head, *tail;
    DueNode<T> *setPos();
    int Size;
};

#endif //_QUEUE_H
Dueue.cpp
#include "Queue.h"
#include <iostream>
using namespace std;

template<class T>
SQueue<T>::SQueue()
{
    head = tail = 0;
}

template<class T>
SQueue<T>::~SQueue()
{
    head = tail = 0;
}

template<class T>
T SQueue<T>::front()
{
    if(head == tail)
    {
        cout << "queue is empty" << endl;
        return -1;
    }
    return data[head];
}

template<class T>
T SQueue<T>::pop()
{
    if(head == tail)
    {
        cout << "queue is empty" << endl;
        return -1;
    }
    int idx = head;
    head ++;
    return data[idx];
}

template<class T>
bool SQueue<T>::push(const T x)
{
    if(tail == MaxSize)
    {
        cout << "queue is full" << endl;
        return false;
    }
    data[tail ++] = x;
    return true;
}

template<class T>
bool SQueue<T>::isEmpty()
{
    if(head == tail)
        return true;
    return false;
}

template<class T>
void SQueue<T>::clear()
{
    head = tail = 0;
}

template<class T>
int SQueue<T>::size()
{
    return tail-head;
}

/*
                       .::::.
                     .::::::::.
                    :::::::::::  FUCK YOU
                ..:::::::::::'
              '::::::::::::'
                .::::::::::
           '::::::::::::::..
                ..::::::::::::.
              ``::::::::::::::::
               ::::``:::::::::'        .:::.
              ::::'   ':::::'       .::::::::.
            .::::'      ::::     .:::::::'::::.
           .:::'       :::::  .:::::::::' ':::::.
          .::'        :::::.:::::::::'      ':::::.
         .::'         ::::::::::::::'         ``::::.
     ...:::           ::::::::::::'              ``::.
    ````':.          ':::::::::'                  ::::..
                       '.:::::'                    ':'````..
*/

template<class T>
LQueue<T>::LQueue()
{
    head = new LNode<T>(0, NULL);
    tail = head;
}


template<class T>
LQueue<T>::~LQueue()
{
    LNode<T> *cur = head;
    while(cur != NULL)
    {
        LNode<T> *del = cur;
        cur = cur->next_L;
        delete del;
    }
    head = NULL;
    tail = NULL;
}

template<class T>
T LQueue<T>::pop()
{
    if(head == tail || head->next_L == NULL)
    {
        cout << "queue is empty" << endl;
        return -1;
    }
    LNode<T> *p = head->next_L;
    head->next_L = p->next_L;
    T x = p->data;
    if(p == tail)
        tail = head;
    delete p;
    return x;
}

template<class T>
T LQueue<T>::front()
{
    if(head == tail || head->next_L == NULL)
    {
        cout << "queue is empty" << endl;
        return -1;
    }
    return head->next_L->data;
}

template<class T>
int LQueue<T>::size()
{
    LNode<T> *p = head->next_L;
    int cnt = 0;
    while(p != NULL)
    {
        cnt ++;
        p = p->next_L;
    }
    return cnt;
}

template<class T>
void LQueue<T>::clear()
{
    LNode<T> *cur = head->next_L;
    while(cur != NULL)
    {
        LNode<T> *del = cur;
        cur = cur->next_L;
        delete del;
    }
    head->next_L = NULL;
    tail = head;
}

template<class T>
bool LQueue<T>::push(const T x)
{
    LNode<T> *p = new LNode<T>(x, NULL);
    tail->next_L = p;
    tail = p;
    return true;
}

template<class T>
bool LQueue<T>::isEmpty()
{
    if(head == tail)
        return true;
    return false;
}

/*
                           _ooOoo_
                          o8888888o
                          88" . "88
                          (| -_- |)
                           O\ = /O
                       ____/`---'\____
                     .   ' \\| |// `.
                      / \\||| : |||// \
                    / _||||| -:- |||||- \
                      | | \\\ - /// | |
                    | \_| ''\---/'' | |
                     \ .-\__ `-` ___/-. /
                  ___`. .' /--.--\ `. . __
               ."" '< `.___\_<|>_/___.' >'"".
              | | : `- \`.;`\ _ /`;.`/ - ` : | |
                \ \ `-. \_ __\ /__ _/ .-` / /
        ======`-.____`-.___\_____/___.-`____.-'======
                           `=---='

        .............................................
                 佛祖镇楼                 BUG辟易
         佛曰:
                 写字楼里写字间,写字间里程序员;
                 程序人员写程序,又拿程序换酒钱。
                 酒醒只在网上坐,酒醉还来网下眠;
                 酒醉酒醒日复日,网上网下年复年。
                 但愿老死电脑间,不愿鞠躬老板前;
                 奔驰宝马贵者趣,公交自行程序员。
                 别人笑我忒疯癫,我笑自己命太贱;
                 不见满街漂亮妹,哪个归得程序员?
*/

template<class T>
Dueue<T>::Dueue()
{
    head = new DueNode<T>(0, NULL);
    tail = head;
    Size = 0;
}

template<class T>
Dueue<T>::~Dueue()
{
    DueNode<T> *cur = head;
    while(cur != NULL)
    {
        DueNode<T> *del = cur;
        cur = cur->next_L;
        delete del;
    }
    head = tail = NULL;
    Size = 0;
}

template<class T>
int Dueue<T>::size()
{
    return Size;
}

template<class T>
bool Dueue<T>::isEmpty()
{
    if(head == tail)
        return true;
    return false;
}

template<class T>
void Dueue<T>::clear()
{
    DueNode<T> *p = head->next_L;
    while(p != NULL)
    {
        DueNode<T> *del = p;
        p = p->next_L;
        delete del;
    }
    head->next_L = NULL;
    Size = 0;
    tail = head;
}

template<class T>
T Dueue<T>::back()
{
    return tail->data;
}

template<class T>
T Dueue<T>::front()
{
    DueNode<T> *p = head->next_L;
    return p->data;
}

template<class T>
DueNode<T> *Dueue<T>::setPos()
{
    DueNode<T> *p;
    p = head;
    while(p != NULL && p->next_L != tail)
    {
        p = p->next_L;
    }
    return p;
}

template<class T>
T Dueue<T>::pop_back()
{
    DueNode<T> *p = setPos();
    const T x = tail->data;
    p->next_L = NULL;
    delete tail;
    tail = p;
    Size --;
    return x;
}

template<class T>
T Dueue<T>::pop_front()
{
    DueNode<T> *p = head->next_L;
    const T x = p->data;
    head->next_L = p->next_L;
    if(p == tail)
        tail = head;
    delete p;
    Size --;
    return x;
}

template<class T>
bool Dueue<T>::push_back(const T x)
{
    DueNode<T> *p = new DueNode<T>(x, NULL);
    tail->next_L = p;
    tail = p;
    Size ++;
    return true;
}

template<class T>
bool Dueue<T>::push_front(const T x)
{
    DueNode<T> *p = new DueNode<T>(x, NULL);
    DueNode<T> *q = head->next_L;
    head->next_L = p;
    p->next_L = q;
    Size ++;
    return true;
}

template<class T>
void Dueue<T>::Print()
{
    DueNode<T> *p = head->next_L;
    while(p != NULL)
    {
        cout << p->data << " ";
        p = p->next_L;
    }
    cout << endl;
}

栈的应用

#include <iostream>
#include "Stack.h"
#include "Stack.cpp"
#include "Queue.h"
#include "Queue.cpp"
using namespace std;


//栈的括号匹配
void func1(const string a)
{
    LStack<char> s;
    for(int i = 0; i < a.length(); ++ i)
    {
        if(a[i] == '(' || a[i] == '{' || a[i] == '[')
        {
            s.push(a[i]);
        } 
        else
        {
            char e = s.pop();
            if(e == '(' && a[i] != ')')
            {
                cout << "匹配失败" << endl;
                break;
            }
            else if(e == '[' && a[i] != ']')
            {
                cout << "匹配失败" << endl;
                break;
            }
            else if(e == '{' && a[i] != '}')
            {
                cout << "匹配失败" << endl;
                break;
            }
        }
    }
    if(s.isEmpty())
    {
        cout << "匹配成功" << endl;
    }
    else 
    {
        cout << "匹配失败" << endl;
    }
}

//判断是否为操作符
bool isOperator(char ch)
{
    if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
        return true;
    return false;
}
//获得优先级
int getPriority(char ch)
{
    int level = 0;

    switch(ch)
    {
        case '(':
            level = 1;
            break;
        case '+':
        case '-':
            level = 2;
            break;
        case '*':
        case '/':
            level = 3;
            break;
        default:
            break;
    }
    return level;
}

//栈中缀表达式转后缀表达式
void func2()
{
    string a, b = "";
    cout << "请输入一个中缀表达式: ";
    cin >> a;
    LStack<char> s;
    int len = a.length();
    int i = 0;
    while(i < len)
    {
        if(a[i] >= '0' && a[i] <= '9')
        {
            do
            {
                b += a[i];
                i ++;
            } while (a[i] >= '0' && a[i] <= '9');
            b += ' ';
        }
        else if(a[i] == '(')
        {
            s.push(a[i]);
            i ++;
        }
        else if(isOperator(a[i]))
        {
            if(s.isEmpty())
            {
                s.push(a[i]);
                i ++;
            }
            else
            {
                while(!s.isEmpty())
                {
                    char c = s.top();
                    if(getPriority(a[i]) <= getPriority(c))
                    {
                        b += c;
                        b += ' ';
                        s.pop();
                    }
                    else 
                        break;
                }
                s.push(a[i]);
                i ++;
            }
        }
        else if(a[i] == ')')
        {
            while(s.top() != '(')
            {
                b += s.top();
                b += ' ';
                s.pop();
            }
            s.pop();
            i ++;
        }
    }
    while(!s.isEmpty())
    {
        b += s.top();
        b += ' ';
        s.pop();
    }
    cout << b << endl;
}


//后缀表达式求值
void func3()
{
    string a;
    cout << "请输入一个后缀表达式: ";
    getline(cin, a);
    LStack<int> s;
    int i = 0, len = a.length();
    while(i < len)
    {
        if(a[i] >= '0' && a[i] <= '9')
        {
            int now = 0;
            while(a[i] >= '0' && a[i] <= '9')
            {
                now = now*10+(a[i]-'0');
                i ++;
            }
            s.push(now);
        }
        else if(a[i] == ' ')
        {
            i ++;
            continue;
        }
        else
        {
            int num1 = s.pop();
            int num2 = s.pop();
            if(a[i] == '+')
            {
                s.push(num1+num2);
            }
            if(a[i] == '/')
            {
                s.push(num1/num2);
            }
            if(a[i] == '*')
            {
                s.push(num1*num2);
            }
            if(a[i] == '-')
            {
                s.push(num1-num2);
            }
        }
        i ++;
    }
    cout << s.top() << endl;
}


int main()
{
    func3();
    return 0;
}

队列的应用

图的层次遍历,深度优先搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值