顺序栈,共享栈以及链栈的相关操作

栈,后进先出的数据结构,可分为顺序栈,共享栈以及链栈。首先我们先说一下顺序栈。

顺序栈

这里写图片描述
顺序栈其实是在数组的基础上实现的,其数据结构定义了一个用来存储元素的数组和一个指向栈顶的指针。

class SeqStack{
    Object[] data;;
    int top;
}

定义好数据结构以后,首先先看一下顺序栈的初始化。

    public static SeqStack initEmptyStack(){
        SeqStack seqStack=new SeqStack();
        seqStack.data=new Object[MAX_SIZE];
        seqStack.top=-1;
        return seqStack;
    }

空栈的初始化根很简单,只需要将栈顶指针设为-1即可。接下来看判断栈是否为空的函数

    public static boolean isEmpty(SeqStack seqStack){
        if(seqStack.top==-1)
            return true;
        return false;
    }

由于默认使用栈顶指针等于-1表示空栈,所以在判空时只需判断栈顶指针是否为-1
接下来是进栈函数。其思想是:如果没有超出栈的大小,则进栈,并将栈顶指针加1,否则进栈失败

    public static boolean push(SeqStack seqStack,Object value){
        if(seqStack.top+1==MAX_SIZE){
            return false;
        }
        seqStack.data[++seqStack.top]=value;
        return true;

    }

最后是出栈,出栈的思想也很简单,如果栈为空,返回null,否则返回栈顶元素的值,并将栈顶指针的值减一

    public static Object pop(SeqStack seqStack){
        if(isEmpty(seqStack)){
            return null;
        }
        int top=seqStack.top;
        seqStack.top--;
        return seqStack.data[top];
    }

共享栈

这里写图片描述
共享栈是在顺序栈的基础上完成的,它利用栈底的位置不变,栈顶位置动态变化的特性,两个栈底分别是-1和MAX_SIZE-1,而他们的栈顶位置都会向中间方向延伸。按照此思想,我们给出共享栈的数据结构

class DupSeqStack {
    Object[] data;
    int leftTop;
    int rightTop;
}

建立好数据结构,先对共享栈进行初始化。

    public static  DupSeqStack initEmptyDumpSeqStack(){
        DupSeqStack dupSeqStack=new DupSeqStack();
        dupSeqStack.data=new Object[MAX_SIZE];
        dupSeqStack.leftTop=-1;
        dupSeqStack.rightTop=MAX_SIZE;
        return  dupSeqStack;
    }

由于将栈底位置分别设为-1和MAX_SIZE,所以在初始化空栈时只需要将leftTop设为-1,rightTop设为MAX_SIZE。接着就是比较常用的函数进栈和出栈。它的思想和顺序栈的思想是一样的,只不过我们在它的基础上加了一个标志flag来判断左进栈还是右进栈(或者是左出栈,右出栈)。当flag为真时,代表左进栈或者是左出栈;当flag为假时,代表右进栈或者右出栈。具体代码如下

    //入栈
    public static boolean push(DupSeqStack dupSeqStack,boolean flag,Object value){
        if(dupSeqStack.leftTop+1==dupSeqStack.rightTop){
            return false;
        }
        if(flag){
            dupSeqStack.data[++dupSeqStack.leftTop]=value;
        }else{
            dupSeqStack.data[--dupSeqStack.rightTop]=value;
        }
        return true;
    }
    //出栈
    public static Object pop(DupSeqStack dupSeqStack,boolean flag){
        if(flag){
            if(dupSeqStack.leftTop==-1){
                return null;
            }else{

                return dupSeqStack.data[dupSeqStack.leftTop--];
            }
        }else{
            if(dupSeqStack.rightTop==MAX_SIZE){
                return null;
            }else{
                return dupSeqStack.data[dupSeqStack.rightTop++];
            }
        }
    }

链栈

这里写图片描述
所谓链栈就是用链表的形式将元素组合起来,并让其符合栈后进先出的特性。为了达到这一目的,我们可以利用链表头插法的特性实现。先看一下它的数据结构

class LinkStack{
    Object value;
    LinkStack next;
}

链栈的数据结构其实和链表的一样。

    public static boolean push(LinkStack top,Object value){
        LinkStack node=new LinkStack();
        node.value=value;
        node.next=top.next;
        top.next=node;
        return true;
    }

上述代码采用头插法进行入栈,具体思想可以参考单链表的创建
最后就是出栈方法。我们得判断栈顶指针是否为空,不为空则出栈,并返回其值。

    public static Object pop(LinkStack top){
        if(top.next!=null){
            LinkStack node=top.next;
            top.next=node.next;
            return node.value;
        }
        return null;
    }

总结

共享栈和顺序栈都是基于数组实现的,所以在此我们先将其归为一类,统称为顺序栈。接下来我们就说一下链栈和顺序栈的区别:顺序栈需要分配固定的空间,无法避免因数组空间用光导致溢出的问题,也无法避免空间浪费的问题,而链栈则是动态分配空间,通常是不会出现栈满的情况,正是因为在使用的时候动态分配,所以也不会出现空间浪费的情况

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值