栈的总结_legend



stack

1)栈的基本知识:

 

        1.1)栈的存储结构:

        1.2)栈的特点:

2)栈的基本操作:

        2.1)顺序栈的基本操作:

        2.2)链式栈的基本操作:

3)顺序栈:seqStack

4)链式栈:linkStack

5)共享栈:shareStack

6)栈的应用:

        6.1)表达式求值:expressionValue

        6.2)括号匹配match

        6.3)求解迷宫问题:maze

7)栈的扩展操作:

        (7.1)       O1)求栈中最小值:

 

-------------------------------------------

1)栈的基本知识:

 

        1.1)栈的存储结构:

        顺序栈,链式栈;

 

        1.2)栈的特点:

 

        后进先出,头进头出,插入和删除在栈顶进行;

        栈是一种插入删除受限制的线性表。

 

2)栈的基本操作:

        2.1)顺序栈的基本操作:

                  2.1)初始化栈init

                  2.2)栈空isEmpty

                  2.3)栈满isFull

                  2.4)进栈push

                  2.5)出栈pop

                  2.6)取栈顶getTop

                  2.7)栈的大小:getSize:

 

        2.2)链式栈的基本操作:

                  3.1)初始化栈init

                  3.2)栈空isEmpty

                  3.3)进栈push

                  3.4)出栈pop

                  3.5)取栈顶getTop

                  2.6)栈的大小:getSize:

                  (注:链式栈不存在栈满)

 

3)顺序栈:seqStack

 

顺序栈通常用一个数组来存储栈中元素,用下标为0的一端作为栈底,

栈顶设置一个指针top指示栈中元素的变化,称为栈顶指针。

 

        3.1)顺序栈的定义:

 

        typedefstruct{

        ElemTypearray[Maxsize];

        inttop;

        }SqStack;

 

        3.2)顺序栈的五要素:

 

                  (3.2.1)方法一:

                  .       栈空条件:s.top=-1

                  .       栈满条件: s.top=Maxsize-1

                  .       元素e进栈:s.top++;s.array[s.top]=e;

                  .       元素出栈:e=s.array[s.top];s.top--;

                  .       获取栈顶: returns.array[top];

 

                  解析:初始化top=-1;则当前的top这个位置,已经被填入了元素;

                  所以进栈需要top++;然后赋值;

                  出栈,直接去top处的值,然后top--;

                  栈满的条件是top=Maxsize-1;

                  获取栈顶: returnarray[top];

 

                  (3.2.2)方法二:

 

                  .       栈空条件:s.top=0

                  .       栈满条件: s.top=Maxsize

                  .       元素e进栈:s.array[s.top]=e;s.top++;

                  .       元素出栈:s.top--;e=s.array[s.top];

                  .       获取栈顶: returns.array[top-1];

 

                  解析:初始化top=0,表示当前top这个位置还没有元素填充,

                  填充的是top-1;

 

        3.3)顺序栈的基本操作代码:

 

http://blog.csdn.net/legend050709/article/details/28256785

 

4)链式栈:linkStack

        4.1)链式栈的定义:

        typedefstruct linkNode{

        elemTypeelement;

        linkNode*next;

        }linkNode;

 

class linkStack{

     public :

     linkNode* topNode;

     int size;/*可有可无*/

     }

 

        4.2)链式栈的操作:

        .       栈空:topNode=NULL orsize=0;

                  (不带头节点的链式栈)

        .       进栈:头插法:建立一个newnode,更新topNode;

        .       出栈:删除首节点,更新topNode;

 

        4.3)链式栈的基本操作代码:

http://blog.csdn.net/legend050709/article/details/28257305

 

5)共享栈:shareStack

        5.1)共享栈的图解:

        5.2)共享栈的解析:

 

        两个栈共享一个数组vector[0~MaxSize-1]的空间,从而构成共享栈,数组vector的两端是固定的,分别作为栈1,和栈2的栈底。

 

        5.3)共享栈的操作:

                  5.3.1)栈1的操作:

                  .       栈空: top1=-1;

                  .       栈满: top1=top2-1;

                  .       元素e进栈: top1++;shareArray[top1]=e;

                  .       出栈:e=shareArray[top1];top1--;

 

                  5.3.2)栈2的操作:

                .       栈空:top2=MaxSize-1;

                  .       栈满: top2=top1+1;

                  .       元素e进栈: top2--;shareArray[top2]=e;

                  .       元素出栈:e=shareArray[top2];top2++;

 

                  5.4)共享栈的操作代码:

http://blog.csdn.net/legend050709/article/details/28257699

 

6)栈的应用:

 

        6.1)表达式求值:expressionValue

 

                  6.1.1)解析:()、*/+-这几种符号的优先级是不一样的,中缀表达式是有优先级的表达式,不便于在程序中处理,后缀表达式是一种非优先级的表达式,而且不会出现括号。

                  6.1.2)步骤:

                           1)中缀表达式转后缀表达式:

 

                           分析:     后缀表达式与表达式的操作数的排列次序完全相同,只是运算符改变了次序。

 

                           所以:

                           1)若读到一个操作数,就把它作为后缀表达式的一部分输出;

                           2)对于运算符的处理,系统需设置一个存放运算符的栈。

 

                           分析:初始时,栈顶设置一个界限符#(与表达式结束符#配成一对)

     每当读到一个运算符时,就将其优先级与栈顶位置运算符优先级进行比较,以决定是把所读到的运算符进栈,还是将栈顶位置的运算符作为后缀表达式的一部分输出。

 

     因为:     对于任意两个相继出现的运算符θ1θ2,它们之间的优先关系至多是下面三种关系之一:

 

       θ1<θ2,θ1的优先级低于θ2

                   θ1=θ2,θ1的优先级等于θ2

                   θ1>θ2,θ1的优先级高于θ2

 

             2)优先级解析:

 

             对于+-*/()#,这几种运算符来说,其优先关系可以由算术四则运算规则得到。

                 1)先乘除,后加减;

                           2)从左到右算;

                           3)先括号内,后括号外。

                           A、由(1*/ > +-

                           B、由(2*>// >* +>-->+

                           C、由(2)对于+-*/,当θ1=θ2时,令θ1>θ2,即+>+->-*>*/>/

                           D、由(3+-*/的优先级均低于“(”,但高于“)

                           注:即:+-*/的优先级均低于它们后面的“(

                           高于它们后面的)”。

                           

 

                           E、由(3)“(”的优先级均低于+-*/(

                    )”的优先级均高于 +-*/)

              (注:即:(”的优先级均低于它后面的+-*/( 

              )”的优先级均高于它后面的+-*/)

              

 

 

                           F、“( =)”,表示当左右括号相遇时,括号内的运算已经完成;

                           

                           H、“#”是表达式的结束符,为了算法简洁,在表达式的最左边也需设一个“#”,构成整个表达式的一对括号;

                           左“#”的优先级低于+-*/(

                            +-*/)的优先级高于“#”(结束符);

                            “#”=“#”表示整个表达式处理完毕。

 

                            注意:“)”与“(”,“#”与“)”以及“(”与“#”之间无优先关系,因为表达式中不允许它们相继出现(若出现,则表达式有错),一旦遇见,则可以认为出现了语法错误。

--------------------

                            中缀表达式转为后缀表达式的算法步骤:

 

1)置运算符栈s为空栈,然后将表达式的起始符“#”入栈;

2)循环:依次读入中缀表达式中一个单词;

 

        A、若是操作数,就将其输出,接着读下一个字符;

        B、若是运算符,就赋予x2,比较x2与栈顶运算符x1的优先级;

                  1.     x2的优先级高于x1,则将x2进栈,读下一个单词;

                  2.     x2的优先级低于x1x1退栈,并作为后缀表达式的一个单词输出,再转B(即继续比较x2与新的栈顶运算符x1);

                  3.     x2的优先级等于x1,且x1为“(”,x2为“)”,则x1退栈,然后继续读下一个单词;

                  4.     x2的优先级等于x1,且x1为“#”,x2也为“#”,则算法结束。

 

范例:

                  图解1:中缀-后缀1

                  图解2:中缀-后缀2


 

                           2)后缀表达式求值:

                           思路:遍历后缀表达式,遇到非操作符的字符则直接压入栈中,如果遇到操作符则从栈中弹出两个对象,进行对应的操作,然后将计算的结果又压入栈中。继续遍历,直到表达式被遍历完成,此时栈中保存的值也就是当前表达式的值。

 

                           注意:除法和减法的操作数顺序问题以及除数不能为0的,因为第一次退栈的操作数是运算符后的操作数,第二次退栈的操作数是运算符前的操作数。

 

                  6.1.3)中缀表达式->后缀表达式:

                  

                           中缀表达式:a*b+c*d-e/f

                           后缀表达式:ab*cd*+ef/

 

                  6.1.4)表达式求值代码实现:

 

                  http://blog.csdn.net/legend050709/article/details/28255925

 

代码实现2(简洁版):

http://blog.csdn.net/legend050709/article/details/28620571

 

 

        6.2)括号匹配match

 

        代码:

http://blog.csdn.net/legend050709/article/details/28256275

 

 

        6.3)求解迷宫问题:maze

        

代码实现2_C++语言(推荐) :

http://blog.csdn.net/legend050709/article/details/28674223

 

 迷宫C实现:

http://blog.csdn.net/legend050709/article/details/29396899

        6.4)进制转换:

 

                  6.4.1)图解:

                  6.4.2)思想:

                  如:十进制整数转换成n进制:除n取余倒着数(栈实现)

 

                  6.4.3)代码实现:

 

http://blog.csdn.net/legend050709/article/details/28256035

 

 

 

 

 

 

        6.5)路径探索之保存路径:

 

 

7)栈的扩展操作:

 

(7.1)       O1)求栈中最小值:

 

http://blog.csdn.net/legend050709/article/details/29390271

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值