6.栈

栈的作用:

有的同学可能会觉得,用数组或链表直接实现功能不就行了吗?干嘛要引入栈这样的数据结构呢?这个问题问的好。
其实这和我们明明有两只脚可以走路,干嘛还要乘汽车、火车、飞机一样。理论上,陆地上的任何地方,你都可以靠双脚走到的,可那需要多少时间和精力呢?
我们更关注的是到达而不是如何去的过程。
栈的引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决的问题核心。反之,像数组等,因为要分散精力去考虑数组的下标
增减等细节问题,反而掩盖了问题的本质。
所以现在的许多高级语言,比如java、c#等都有对栈结构的封装,你可以不用关注它的实现细节,就可以直接使用Stack的push和pop方法,非常方便。
/*********************
 栈(stack) 的结构类似与手枪的弹夹,后进先出;
 浏览器的“后退”键就是通过栈的结构来实现的
 栈(stack)是限定仅在表尾进行插入和删除的线性表。
 理解栈的定义需要注意:
    首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。
定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。
 ********************/

/*
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
*/

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
//Status是函数的返回类型,其值是函数结果状态代码,如OK等

#define MAXSIZE 20      /*存储空间初始化分配量*/
typedef int ElemType;   /*ElemType 类型根据实际情况而定,这里假设为int */

/*
栈的结构定义
SElemType 类型根据实际情况而定,这里假设为int
*/
typedef int SElemType;
typedef struct 
{
    SElemType data[MAXSIZE];
    //用于栈顶指针
    int top;
}SqStack;

/*
进栈操作push
插入元素e为新的栈顶元素
*/
Status Push(SqStack *S, SElemType e)
{
    /*栈满*/
    if(S->top == MAXSIZE - 1)
    {
        return ERROR;
    }
    /*栈顶指针增加一*/
    S->top++;
    /*将新插入元素赋值给栈顶空间*/
    S->data[S->top] = e;
    return OK;
}

/*出栈pop*/
Status Pop(SqStack *S, SElemType *e)
{
    if(S->top == -1)
        return ERROR;
    /*将要删除的栈顶元素赋值给e*/
    *e = S->data[S->top];
    /*栈顶指针减一*/
    S->top--;
    return OK;
}

 两栈共享空间

//4.5 两栈共享空间
typedef struct
{
    SElemType data[MAXSIZE];
    int top1;       /*栈1栈顶指针*/
    int top2;       /*栈2栈顶指针*/
} SqDoubleStack;

/*插入元素e为新的栈顶元素*/
Status Push(SqDoubleStack *S, SElemType e, int stackNumber)
{
    /*栈已满,不能再push新元素了*/
    if (S->top1+1 == S->top2)
        return ERROR;
    /*栈1有元素进栈*/
    if (stackNumber == 1)
        S->data[++S->top1] = e;
    /*栈2有元素进栈*/
    else if(stackNumber == 2)
        /*若栈2则先top2-1后给数组元素赋值*/
        S->data[--S->top2] = e;
    return OK;
}

Status Pop(SqDoubleStack *S, SElemType *e, int stackNumber)
{
    if (stackNumber == 1)
    {
        /*说明栈1已经是空栈,溢出*/
        if (S->top1 == -1)
            return ERROR;
        /*将栈1的栈顶元素出栈*/
        *e = S->data[S->top1--];
    }
    else if (stackNumber == 2)
    {
        /*说明栈2已经是空栈,溢出*/
        if (S->top2 == MAXSIZE)
            return ERROR;
        /*将栈2的栈顶元素出栈,溢出*/
        *e = S->data[S->top2++];
    }
    return OK;
}

猜你喜欢

转载自www.cnblogs.com/go-ahead-wsg/p/13194889.html
今日推荐