《大话数据结构》读书笔记(四)

4.1 栈的定义

4.1.1 栈的概念

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。

我们允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为 空栈。栈又称为后进先出的线性表,简称LIFO结构。

理解栈的定义需要注意:

1.他是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。是一种特殊的线性表,他的特殊之处就在于限制了这个线性表的插入和删除位置,它始终只在栈顶进行,这也就使得:栈底是固定的,最先进栈的只能在栈底。

栈的插入操作,叫作进栈,也称压栈、入栈。

栈的删除操作,叫作出栈,也有叫作弹栈。

4.1.2 进栈出栈变化形式

最先进栈的元素,是不是就只能是最后出栈呢?

答案是不一定,要看什么情况。栈对线性表的插入和删除的位置进行了限制,并没有对元素进出的时间进行限制,也就是说,在不是所有元素都进栈的情况下,事先进去的元素也可以出栈,只要保证是栈顶元素出栈就可以。

案例:我们现在是有3个整型数字元素1、2、3依次进栈,会有哪些出栈次序?

第一种:1、2、3进,在3、2、1出。出栈次序为 321.

第二种:1进,1出,2进,2出,3进,3出。出栈次序为:123.

第三种:1进,2进,2出,1出,3进,3出。出栈次序为:213.

第四种:1进,1出,2进,3进,3出,2出。出栈次序为:132.

第五种:1进,2进,2出,3进,3出,1出。出栈次序为:231.

4.2栈的抽象数据类型

ADT 栈(stack)

DATA

          同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。

Operation

           InitStack ( *S ) :初始化操作,建立一个空栈S。

           DestroyStack( *S ):若栈存在,则销毁它。

           ClearStack( *S ):将栈清空。

           StackEmpty( S ):若栈为空,返回true,否则返回false。

            GetTop(S , *e):若栈存在且为非空,用e返回S的栈顶元素。

            Push( *S , e ):若栈S存在,插入新元素e到栈S中并成为栈顶元素。

            Pop( *S , *e ):删除栈S中栈顶元素,并用e返回其值。

            StackLength ( S ):返回栈S的元素个数。

endADT

4.3 栈的顺序存储结构及实现

4.3.1 栈的顺序存储结构

栈的结构定义

typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */

typedef struct

{

         SElemType data[MAXSIZE] ;

          int top; /* 用于栈顶指针 */

}SqStack;

4.3.2 栈的顺序存储结构--进栈操作

进栈的push

/* 插入元素e 为新的栈顶元素 */

status push ( SqStack *S ,SElemType e )

{

         if( s->top == MAXSIZE -1 )  {                                                  /* 栈满 */

                  return ERROR;

          }

          S -> top ++;                                                                         /* 栈顶指针加一 */

          S ->data[ S -> top ] = e;                                                      /* 将新插入元素复制给栈顶空间 */

           return OK;

}

4.3.3 栈的顺序存储结构----出栈操作

/* 若栈不空,则删除S的栈顶元素,用 e 返回其值,并返回OK;否则返回ERROR */

status Pop ( SqStack *S , SElemType *e )

{

               if ( S ->top == -1 ){

                        return ERROR;

                }

                *e = S -> data[S -> top ];                                             /* 将要删除的栈顶元素赋值给e */

                 S -> top --;                                                                 /* 栈顶指针减一 */

                 return OK;

}

进栈和出栈都没有涉及循环语句,因此时间复杂度均为 O( 1 )。

4.4 两栈共享空间

/* 两栈共享空间结构 */

typedef struct

{

           SElemType data[MAXSIZE];

           int top1;                               /* 栈1 栈顶指针 */

           int top2;                               /* 栈2 栈顶指针 */

}SqDoubleStack;

对于两栈共享空间的push方法,我们除了要插入元素值参数值外,还需要添加一个判断栈1还是栈2的参数stackNumber。

/* 插入元素 e 为新的栈顶元素 */

status push ( SqDoubleStack *S , SElemType e, int stackNumber )

{

            if ( S -> top1 +1 == top2 ) {                                        /* 栈已满,不能在push了 */

                      return ERROR;

             }

             if ( stackNumber == 1 ){                                                /* 栈1 有元素 */

                         S -> data[ ++S -> top1 ] = e;                            /* 若栈1则先top1 +1 后给数据元素赋值 */

              } else if ( stackNumber == 2 ){                                     /* 栈2有元素 */

                         S ->data[ -- S -> top2 ] = e;                               /* 若栈2则先 top2 - 1后给数据元素赋值 */

               }

              return OK;

}

对于两栈共享空间的pop方法,参数就只是判断栈1 和栈2 的参数stackNumber。

/* 若栈不空,则删除S的栈顶元素,用e 返回其值,并返回ok;否则返回error */

status pop ( SqDoubleStack *S , SElemType *e , int stackNumber )

{

             if ( stackNumber == 1 ){

                     if ( S ->top1 == -1 ){

                            return ERROR;                                                    /* 说明栈1已经是空栈了,溢出 */

                     }

                     *e = S ->data [ S->top1 -- ];                                         /* 将栈1的栈顶元素出栈 */

             }else if ( stackNumber == 2 ){

                      if ( S ->top2 == MAXSIZE ){

                              return ERROR;                                                    /* 说明栈2已经是空栈了,溢出 */

                        }

                        *e = S ->data [ S->top2 ++ ];                                       /* 将栈2的栈顶元素出栈 */

             }

             return OK;

}

猜你喜欢

转载自www.cnblogs.com/cjn93/p/9342845.html