顺序栈的实现与解析

顺序栈的实现与解析

顺序栈

顺序栈,即栈的顺序存储结构利用一组地址连续的存储单元依次存放自栈低到栈顶的数据元素,同时附设指针top指向栈顶元素在顺序栈中的位置。栈的特性,先进后出,后进先出,推荐可以看一看电影盗梦空间,跟函数的调用顺序有关系

栈顶

表示栈的线性表的表尾端

栈底

表示栈的线性表的表头端

基本操作

1.进栈
2.退栈
3.得到栈顶元素
5.栈的初始化和销毁

代码实现

头文件

#ifndef MYSTACK_H
#define MYSTACK_H
#include <iostream>
#include <stdexcept>

using namespace std;

//顺序栈的实现与解析
template <typename Type>
class MyStack
{
    //声明为友元函数,可以直接在类外部使用
    template <typename T>
    friend ostream &operator <<(ostream &os,const MyStack<T> &stack);

public:
    MyStack(int stackCapacity = 16);
    ~MyStack();

    /*非静态成员函数后面加const,表示成员函数隐含传入的this指针为const指针,
     *决定了在该成员函数中,任意修改它所在类的成员的操作是不允许的,增加了代码的可维护性
     **/
    
    //判断栈是否为空
    bool isEmpty() const;


    /*
     * const在*前面表示这是一个字符串常量指针,它所指向的变量值不能被修改,但是这个指针的指向变量的地址可以改变
     * const在*的后面,则表示这是一个指针常量,它指向的变量值不能被修改,但可以修改他所指向的变量的地址
     * */
    
    //进栈
    void push(const Type &item);
    
    //退栈
    void pop() throw(std::range_error);  //表示pop只能抛出range_error类型的异常  range_error:内部计算时发生区间错误时抛出

    /*
     * 在函数之前加const修饰了返回值,加&表示对函数返回值的引用
     **/
    
    //返回栈顶元素
    const Type &top() const throw(std::range_error);

private:
    Type *m_stack;
    int m_top;       //栈顶指针
    int m_capacity;  //表示栈顶容量
};

#endif // MYSTACK_H

源文件

#include "mystack.h"

//构造函数
template <typename Type>
MyStack<Type>::MyStack(int stackCapacity):m_capacity(stackCapacity)
{
    if(m_capacity<1)
        throw range_error("new size must >= 1");

    //申请内存并构造对象
    m_stack = new Type[m_capacity];
    if(m_stack == NULL)
        throw bad_alloc();  //new 操作失败时会抛出

    m_top = -1;

}

//析构函数
template <typename Type>
MyStack<Type>::~MyStack()
{
    //析构内存并释放对象
    delete []m_stack;
    m_top = -1; //将top指针指向无效
    m_capacity = 0;
}


// "*&"为指针引用,可以修改指针里存放的地址
//改变数组大小,扩大二倍
template <typename Type>
static void changeSize(Type *&array,int oldSize,int newSize)
throw(range_error,bad_alloc)
{
    if(newSize < 0)
        throw range_error("new size must >= 0");

    Type *tmp = new Type[newSize];

    if(tmp == NULL)
        throw bad_alloc();

    int minSize = std::min(oldSize,newSize);
    std::copy(array,array+minSize,tmp);

    delete []array; //将原数组释放掉
    array = tmp;    //将原指针指向新申请的数组
}

//进栈
template <typename Type>
void MyStack<Type>::push(const Type &item)
{
    //数组最大容量为m_capacity,因此数组最大下标为m_capacity-1
    if(m_top >= m_capacity-1)
    {
        //一次扩容2倍
       changeSize(m_stack,m_capacity,m_capacity*2);
       m_capacity *=2;
    }

    m_stack[++m_top] = item;
}


//栈是否为空
template <typename Type>
bool MyStack<Type>::isEmpty() const
{
    return -1 == m_top;
}


template <typename Type>
const Type &MyStack<Type>::top() const
throw(std::range_error)
{
    if(isEmpty())
        throw range_error("stack is empty");

    return m_stack[m_top];
}

//出栈
template <typename Type>
void MyStack<Type>::pop()
throw(range_error)
{
    if(isEmpty())
        throw range_error("stack is empty");

    //如果该栈保存的对象类型的元素,则需要显示调用其析构函数
    //同时还需要将栈顶指针下移
    m_stack[m_top--].~Type();
}

//输出栈的所有内容,以便调试,重载运算符<<
template <typename Type>
ostream &operator <<(ostream &os,const MyStack<Type> &stack)
{
    os << stack.m_stack[0];
    for(int i=1;i <= stack.m_top; ++i)
        os << ' '<< stack.m_stack[i];

    return os;
}

main函数

#include <iostream>
#include <stdexcept>
#include "mystack.h"
#include "mystack.cpp"
using namespace std;


int main()
{
    MyStack<int>  myStack;
    myStack.push(10);
    myStack.push(22);
    myStack.push(15);

    cout << myStack <<endl;
    try
    {
        cout << "Top = " << myStack.top() << endl;
        myStack.pop();
        cout << "Top = " << myStack.top() << endl;
        myStack.pop();
        cout << "Top = " << myStack.top() << endl;
        myStack.pop();
        cout << "Top = " << myStack.top() << endl;
    }
    catch (const std::exception &e)
    {
        cout << e.what() << endl;
    }

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来帮您解决这个问题。 首先我们需要明确一下顺序栈的定义和基本操作。顺序栈就是一种顺序存储结构的栈,可以使用数组来实现。其基本操作有入栈(push)和出栈(pop)。入栈即将元素插入到栈顶,出栈即将栈顶元素删除。 接下来我们可以开始程序。根据您的要求,我们需要实现加减乘除操作并且判断括号的优先级。下面是完整的程序代码,并且每个步骤都有详细注释: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> // 定义顺序栈结构体 typedef struct stack { char data[100]; // 存储栈中元素的数组 int top; // 栈顶指针 } Stack; // 初始化栈 void initStack(Stack *s) { s->top = -1; } // 判断栈是否为空 int isEmpty(Stack *s) { return s->top == -1 ? 1 : 0; } // 入栈 void push(Stack *s, char c) { s->data[++s->top] = c; } // 出栈 char pop(Stack *s) { if (isEmpty(s)) { printf("Error: stack is empty.\n"); exit(-1); } return s->data[s->top--]; } // 获取栈顶元素 char getTop(Stack *s) { if (isEmpty(s)) { return '\0'; } return s->data[s->top]; } // 判断优先级 int priority(char c) { switch(c) { case '+': case '-': return 1; case '*': case '/': return 2; default: return 0; } } // 计算表达式的值 int calculate(int a, int b, char op) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; default: return 0; } } // 计算表达式的值 int expValue(char* exp) { Stack opStack, valStack; initStack(&opStack); // 运算符栈初始化 initStack(&valStack); // 数值栈初始化 int i = 0, len = strlen(exp); while (i < len) { if (isdigit(exp[i])) { // 如果当前字符是数字,取出完整的数值并入数值栈 int val = 0; while (i < len && isdigit(exp[i])) { val = val * 10 + exp[i++] - '0'; } push(&valStack, val); } else if (exp[i] == '(') { // 如果当前字符是左括号,入运算符栈 push(&opStack, '('); i++; } else if (exp[i] == ')') { // 如果当前字符是右括号,计算括号内表达式的值 while (getTop(&opStack) != '(') { char op = pop(&opStack); int b = pop(&valStack); int a = pop(&valStack); int val = calculate(a, b, op); push(&valStack, val); } pop(&opStack); // 弹出左括号 i++; } else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { // 如果当前字符是运算符 while (!isEmpty(&opStack) && priority(getTop(&opStack)) >= priority(exp[i])) { // 判断当前运算符与栈顶运算符的优先级 char op = pop(&opStack); int b = pop(&valStack); int a = pop(&valStack); int val = calculate(a, b, op); push(&valStack, val); } push(&opStack, exp[i]); // 当前运算符入栈 i++; } else { // 如果当前字符是空格则忽略 i++; } } while (!isEmpty(&opStack)) { // 计算剩余表达式的结果 char op = pop(&opStack); int b = pop(&valStack); int a = pop(&valStack); int val = calculate(a, b, op); push(&valStack, val); } return pop(&valStack); // 返回数值栈中的结果 } int main() { char exp[] = "(2+3)*(4-1)/5"; int result = expValue(exp); printf("%s = %d\n", exp, result); return 0; } ``` 以上程序使用顺序栈实现解析带有括号的四则运算表达式并计算其结果。每个实现步骤都有详细的注释,您可以根据注释来理解程序的实现过程。您只需要将操作数与运算符按照指定的格式输入表达式即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值