小白学算法1.1——栈

小白学算法1.1——栈

标签: 小白学算法


1.什么是栈

先解释一下什么是算法和数据结构吧~

  • 简单地说,算法就是解决一个问题的方法。有一个很流行的笑话:请问如何把大象放到冰箱里?答:第一步,打开冰箱;第二步,把大象塞进去;第三步,关上冰箱。当然,这是一个非常糟糕甚至失败的算法,因为谁都知道在第二步中大象是塞不进冰箱的,大象相对于冰箱来说实在是太大了。
  • 数据结构是算法的副产品,因为大部分的算法都需要适当的组织数据,而为了组织数据就产生了数据结构。简单地说,数据结构就是就是计算机存储和组织数据的方式。

现在我们来看一下什么是栈吧~

  • 栈是一种非常常见的数据结构,遵循后进先出(last in first out)的规则。可以把栈看做羽毛球筒,数据看成羽毛球,羽毛球可以放在羽毛球筒里面,显而易见,先放进去的羽毛球只能后取出来;后放进去的羽毛球只能先取出来。
  • 栈常见的实现方法有数组和链表
  • 栈常见的操作的有三种:
    • 入栈(push),向栈添加一个元素
    • 出栈(pop),删除栈中最近添加的一个元素并将其作为操作的返回值
    • 检查是否为空(isEmpty)

2.实现一个栈

为了简单快速的说明栈的作用,本文将使用数组的方式来实现栈。首先需要定义一个全局数组和全局const变量,数组用来存储数据,const变量用来定义栈的大小,再定义一个变量用来记录栈顶元素的位置。

const int N = 20;
int Value[N] = {0};//初始化为0
int valPos = 0;

2.1入栈

void push_val(int data)
{
    Value[valPos++] = data;//valPos指向栈顶元素的下一个位置
}

2.2出栈

int pop_val()
{
    return Value[--valPos];
}

2.3检查是否为空

bool is_val_empty()
{
    return !valPos;
}

3.利用双栈求表达式的值

Dijkstra在20世纪60年代发明了一个非常简单的计算算术表达式的算法,该算法需要两个栈来完成计算。一个栈用来存放运算符,一个栈用来保存操作数。表达式由括号、运算符和数值组成。为了简单起见,所有的单元都需要用括号括起来,如(1+((2+3)*(4*5)))

算法流程如下:

  1. 读入一个字符
  2. 如果该字符是左括号,忽略
  3. 如果该字符是数值,压入操作数栈
  4. 如果该字符是操作符,压入操作符栈
  5. 如果该字符是右括号,弹出一个操作符和两个数值,运算之并将运算结果压入操作数栈
  6. 重复1~5直到把表达式的字符读完
  7. 操作数栈最后只会剩下一个元素,就是该表达式的运算结果

C语言实现如下(输入的数值只能是10以内):

#include "stdafx.h"
#include <STDIO.H>

/*************数值栈*************/
const int N = 20;
int Value[N] = {0};//初始化为0
int valPos = 0;

void push_val(int data)
{
    Value[valPos++] = data;
}

int pop_val()
{
    return Value[--valPos];
}

bool is_val_empty()
{
    return !valPos;
}

/*************符号栈*************/
int Operation[N] = {0};//初始化为0
int opePos = 0;

void push_ope(int data)
{
    Operation[opePos++] = data;
}

int pop_ope()
{
    return Operation[--opePos];
}

bool is_ope_empty()
{
    return !opePos;
}

int main(int argc, char* argv[])
{
    printf("欢迎访问我的博客:http://blog.csdn.net/xuelabizp\n");
    printf("请输入算术表达式:\n");
    char ch;
    while((ch=getchar()) != '\n')
    {
        switch(ch)
        {//读取字符,如果是运算符则入栈
            case '(': ;
                break;
            case '+':
            case '-':
            case '*':
            case '/': push_ope(ch);
                break;
            case ')':
                {
                    //如果字符为右括号,弹出运算符和操作数,计算结果并入栈
                    int myVal = pop_val();
                    int myOpe = pop_ope();
                    switch (myOpe)
                    {
                    case '+': myVal = pop_val() + myVal;
                        break;
                    case '-': myVal = pop_val() - myVal;
                        break;
                    case '*': myVal = pop_val() * myVal;
                        break;
                    case '/': myVal = pop_val() / myVal;
                        break;
                    }
                    push_val(myVal);
                }
                break;
            default: push_val(ch - '0');//把字符转化为真正的数值
        }
    }

    printf("The calculation is %d\n", pop_val());
    return 0;
}

运行结果:
result

4.总结

  • 栈是非常常见的数据结构,所以主流语言的标准库都有栈模板,使用起来非常的方便,而且功能更加的丰富。但是,对于新手来说最好能自己实现一次栈,尤其是通过链表来实现栈,不仅非常有意思还能加深对栈的理解
  • 如果不用把每一个括号都打上的话其实也非常得简单,不要忽略左括号即可
  • 本节的代码有一个小小的问题,不知道有人能发现不:-P
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值