小白学算法1.1——栈

来源:互联网 发布:c语言自学步骤 编辑:程序博客网 时间:2024/05/29 15:09

小白学算法1.1——栈

标签: 小白学算法


1.什么是栈

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

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

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

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

2.实现一个栈

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

const int N = 20;int Value[N] = {0};//初始化为0int 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};//初始化为0int 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};//初始化为0int 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 0
原创粉丝点击