栈的顺序结构实现

311 阅读3分钟

阅读本文前情提要

由于本周三开始的Java的学习,到现在学习的语法跟C大同小异,实在不知道写什么,原谅我炒一次冷饭。(写完才发现,还是这么水的冷饭)

栈的顺序存储结构

我们知道,栈仍然属于线性结构的一种,那么栈的顺序存储也是线性表的顺序存储。线性表是用数组实现的,那么栈能否用数组实现呢?
答案是可以。普通的数组肯定是实现不了栈的特性,那么如何给数组添加栈的特性呢?我们需要用到结构体来添加一些功能给数组以实现栈。栈只能由一头插入,所以需要在这个结构体中设置栈底,而数组有两端,由于首元素都存储在栈底,所以采用下标为零的一端作为栈底。同时,出栈和入栈的操作可以添加一个指针来进行。下面是栈的结构定义。

     typedef int SElemType;
     typedef struct{
         SElemType data[MAXSIZE];
         int top;        //栈顶指针
     }SqStack;

栈的顺序存储结构——进栈操作

其实就是通过栈顶指针给数组添加元素,理解起来也没有什么苦难,直接上代码。

bool Push(SqStack *S,SElemType e){
    if(S->top == MAXSIZE-1)//栈满
     {
        return false;
    }
    S->top++;
    s->data[S->top] = e;
    
    return true;
}

栈的顺序存储结构——出栈操作

跟进栈操作一样,判断栈是否空栈,再进行出栈。top == 0 是有一个元素,所以我们定义top == 1时为空栈。代码如下

bool Pop(SqStack *S,SElemType *e)
{
    if(S->top == -1)
        return false;
     *e = S->data[S->top];
     S->top--;
     return true;
}

两栈共享空间

如果我们有两个相同的栈,各自开辟了数组空间,但一个栈是满的,另一个栈确只有几个元素,这样就导致了空间的大大浪费,所以我们可以利用一个数组来实现两个栈。
分别利用数组的两端作为栈底,插入元素时,两栈的栈顶向数组中间延申。
定义结构体代码如下:

typedef struct
{
    SElemType data[MAXSIZE];
    int top1;            //栈1栈顶指针
    int top2;            //栈2栈顶指针
}SqDoubleStack;

既然一个数组有两个栈,那么在进栈的时候,就要确定进栈的是哪一个栈,就要引入一个变量来判断是哪个栈,我们定义为stackNumber。插入元素代码如下:

bool Push (SqDoubleStack *S,SElemType e,int stackNumber)
{
    if(S->top1 + 1 == S->top2)    //判断是否栈满,当top1和top2相遇时,栈满
        return falseif(stackNumber == 1)           //栈1有元素进栈
        S->data[++S->top1] = e;
    else if(stackNumber == 2)         //栈2有元素进栈
        S->data[--S->top2] = e;
     return true;
}

由于代码开头判断了是否满栈,所以不用担心溢出的问题。
对于两栈共享空间的情况,出栈操作也类似,先判断是否空栈,再出栈。

bool Pop (SqDoubleStack *S,SElemType *e,int stackSNumber)
{
    if(stackNumber == 1)
    {
        if(S->top1 == -1)
            return false;
         else
             *e = S->data[S->top1--];
    }
    else if(stackNumber == 2)
    {
        if(S->top2 == -1)
            return false;
         else
             *e = S->data[S->top2++];
    }
    return true;
}