zoukankan      html  css  js  c++  java
  • 栈(代码分解)

    完整代码的链接:https://www.cnblogs.com/ouyang_wsgwz/p/7748058.html

    栈和队列是两种中重要的线性结构。从数据结构的角度来看,栈和队列也是线性表,其特殊的在于栈和队列的基本操作是线性表操作的子集,它们是受限的线性表,因此,可称为限定性的数据结构。

    1.栈(stack)是限定仅在标为之间进行插入或者删除操作的线性表。

      栈顶(Top)。线性表允许进行插入和删除的那一端。

      栈底(Bottom)。固定的,不允许进行插入和删除的另一端。

      空栈。不含任何元素的空表。

    栈的抽象数据类型的类型:

    ADT Stack {

      数据对象:D = { ai | ai ∈ ElemSet, i = 1, 2, …, n,  n≥0 }

      数据关系:R1 = { < ai-1, ai > | ai-1, ai ∈ D, i = 1, 2, …, n }

           约定an端为栈顶,a1端为栈底。

      基本操作:

        InitStack( &S )

          操作结果:构造一个空栈S。

        DestroyStack ( &S )

          初始条件:栈S已存在。

          操作结果:销毁栈S。

        ClearStack( &S )

          初始条件:栈S已存在。

          操作结果:将S清为空栈。

        StackEmpty( S )

          初始条件:栈S已存在。

          操作结果:若S为空栈,则返回TRUE,否则返回FALSE。

        StackLength( S )

          初始条件:栈S已存在。

          操作结果:返回S的数据元素个数,即栈的长度。

        GetTop( S, &e )

          初始条件:栈S已存在且非空。

          操作结果:用e返回S的栈顶元素。

        Push( &S, e )

          初始条件:栈S已存在。

          操作结果:插入元素e为新的栈顶元素。

        Pop( &S, &e )

          初始条件:栈S已存在且非空。

          操作结果:删除S的栈顶元素,并用e返回其值。

        StackTraverse( S, visit() )

          初始条件:栈S已存在且非空。

          操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。

    }ADT Stack

    1.顺序栈的实现

    采用顺序存储的栈称为 顺序栈, 它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶的位置。

      栈的顺序存储类型可描述为:

    1 #define MaxSize 50                //定义栈中元素的最大个数
    2 typedef struct{            
    3     ElemType data[MaxSize];        //存放栈中元素
    4     int top;                    //栈顶指针
    5 } SqStack;

      栈顶指针:S.top,初始时设置 S.top = -1;栈顶元素:S.data[S.top]。

      进栈操作:栈不满时,栈顶指针先加1,再送值到栈顶元素。

      出栈操作:栈非空时,先取栈顶元素值,再将栈顶指针减1。

      栈空条件:S.top == -1;栈满条件:S.top == MasSize - 1;栈长:S.top+1

      由于顺序栈的入栈操作受数组上界的约束,当对栈的最大使用空间估计不足时,有可能发生上溢,此时应及时向用户报告信息,以便于及时处理。

      栈和后面的队列的判空和判慢条件,会因为实际给的条件不同而变化,以上提到的方法以及给出的代码实现只是一些相应的方法,其他情况需要具体问题具体分析。

    2.顺序栈的基本运算

    (1)初始化

     void InitStack(SqStack &S){ S.top = -1; } 

    (2)判栈空

    1 bool StackEmpty(SqStack){
    2     if (S.top == -1)
    3         return true;    //栈空
    4     else 
    5         return false;    //不空
    6 }

    (3)进栈

    1 bool Push(SqStack &S, ElemType x){
    2     if (S.top == MaxSize - 1){        //栈满,报错
    3         return false;        
    4     }    
    5     S.data[++S.top] = x;            //指针先加1,再入栈
    6     return true;
    7 }

    (4)出栈

    1 bool Pop(SqStack &S, ElemType &x){
    2     if (S.top == -1){        //栈空,报错
    3         return false;
    4     }
    5     x = S.data[S.top--];    //先出栈,指针再减1
    6     return true;
    7 }

    (5)读栈顶元素

    1 bool GetTop(SqStack S, ElemType &x) {
    2     if (S.top == -1)     //栈空报错。
    3         return false;
    4     x = S.data[S.top];    //记录栈顶元素
    5     return true;
    6 }

    注:这里栈顶元素指针指向的是栈顶元素,所以进栈时的操作是S.data[++S.top] = x,出栈的操作是 x = S.data[S.top--]。若栈顶指针初始化为 S.top = 0,即栈顶指针指向栈顶元素的下一个位置,则入栈操作变为 S.data[S.top++] = x;出栈操作会变为 x = S.data[--S.top]。相应的栈空、栈满条件也会改变,要灵活应变。

    3.共享栈

      利用栈底位置相对不变的特性,可以让两个顺序栈共享一个一维数据空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸。

      两个栈的栈顶指针都指向栈顶元素,top0 = -1时0号栈为空,top1 = MaxSize 时1号栈为空;仅当两个栈顶指针相邻(top1-top0 = 1)时,判断为栈满。当0号栈进栈时 top0先加1再赋值,1号栈进栈时top1先减1再赋值;出栈时刚好相反。

    优点:共享栈是为了更有效地利用存储空间,两个栈的空间互相调节,只有在整个存储空间被占满的时候才会发生上溢。其存取数据的时间复杂度均为O(1),所以对存取效率没有什么影响。

    栈的链式存储结构

      采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现,并规定所有操作都是在单链表的表头进行的。这里规定链栈没有头结点,Lhead指向栈顶元素。

      栈的链式存储类型可描述为:

    1 typedef struct Linknode{
    2     ElemType data;            //数据域
    3     struct Linknode *next;    //指针域
    4 } *LiStack;                    //栈类型定义

      采用链式存储,便于结点的插入与删除。链栈的操作与链表类似。

  • 相关阅读:
    装饰器
    目录和文件操作
    网络通信过程
    epoll并发
    laravel(包含lumen)框架中的跨域函数实例
    windows使用nginx
    nginx反向代理配置 其实很简单
    前端html页面使用marked点亮你的代码
    PHPWAMP开启SSL,PHPWAMP配置ssl证书
    php接收并存储base64位字符串图片
  • 原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/10805305.html
Copyright © 2011-2022 走看看