数据结构---双端栈

双端栈

定义:一个线性表的两端当做栈底分别进行入栈和出栈的操作,主要利用了栈"栈底位置不变,而栈顶位置动态变化"的特性。

我们把双端栈叫做ArrayDoubleEndStack,双端栈是线性表的一种,更是栈的一个特殊的分类,所以我们可以用动态数组和栈的思想来实现双端栈,毕竟由于其操作的特殊性,并不能借助ArrayList或者ArrayStack实现,所以这里需要从头开始实现双端栈

 

package 动态数组;

public class ArrayDoubleEndStack<E> {
    private  E[] data;//元素的容器
    private int ltop;//左端栈的栈顶ltop=-1,左端栈为空ltop+1表示左端栈中元素的个数
     private int rtop;//右端栈的栈顶rtop=data.length,右端栈为空length-rtop表示右端栈中元素的个数
    private static int DEFAULT_SIZE=10;//双端栈的默认容量
    public ArrayDoubleEndStack(){
        data =(E[]) new Object[DEFAULT_SIZE];
        //对两个标记进行赋值
        rtop=data.length;
        ltop=-1;
    }
    //入栈操作
    public void push(E element,int stackId){
        //如果栈满了,就需要扩容
        if(ltop+1==rtop){
            resize(data.length*2);
        }
        switch (stackId){
            case 0://向左端栈入栈一个元素
                data[++ltop]=element;
                break;
            case 1://向右端栈入栈一个元素
                data[--rtop]=element;
                break;
        }
    }
    //出栈操作
    public E pop(int stackId){
        if(isEmpty(stackId)){
            throw new NullPointerException("stack is null");
        }
        E ret =null;
        switch(stackId){
            case 0:
                ret = data[ltop--];
                break;
            case 1:
                ret = data[rtop++];
                break;
        }
        //如果元素个数<=len/4 && len>DEFAULT_SIZE时,就要进行缩容
        if(size(0)+size(1)==data.length/4&&data.length>DEFAULT_SIZE){
            resize(data.length/2);
        }
          return ret;
    }

    private void resize(int newLength) {
          E [] newData =(E [])new Object[newLength];
          //先去处理左端栈的问题
        for(int i=0;i<=ltop;i++){
            newData[i]=data[i];

        }
        //再去处理右端栈
        int  index= rtop;
        for(int i=newLength-size(1);i<newLength;i++){
            newData[i]=data[index++];
        }
         rtop=newLength-size(1);
        data =newData;
    }

    public int size(int stackId){
        switch (stackId){
            case 0:
                return ltop+1;
            case 1:
                return data.length-rtop;
        }
        return -1;
    }

    //判断某一端的栈是否为空
    private boolean isEmpty(int stackId) {
        switch(stackId){
            case 0:
                return ltop==-1;
            case 1:
                return rtop ==data.length;
        }
        return false;//防止程序报错
    }
    public E peek(int stackId){
        if(isEmpty(stackId)){
            throw  new NullPointerException("stack is null");
        }
        switch (stackId){
            case 0:
                return data[ltop];
            case 1:
                return data[rtop];
        }
        return null;
    }
     public void clear(int stackId){
        switch(stackId){
            case 0:
                ltop=-1;
                break;
            case 1:
                rtop =data.length;

        }
     }
     public String toString(){
        StringBuilder sb =new StringBuilder(String.format("ArrayDoubleEndStack:%d/%d\n",size(0)+size(1),data.length));
        if(isEmpty(0)){
            sb.append("leftStack:[]\n");
        }
        else{
            sb.append("leftStack:[");
            for(int i=0;i<=ltop;i++){
                sb.append(data[i]);
                if(i==ltop){
                    sb.append(']');
                    sb.append('\n');
                }
                else{
                    sb.append(',');
                }
            }

        }
        if(isEmpty(1)){
            sb.append("rightStack:[]");
        }
        else{
            sb.append("rightStack:[");
            for(int i= data.length-1;i>=rtop;i--){
                sb.append(data[i]);
                if(i==rtop){
                    sb.append(']');
                    sb.append('\n');
                }
                else{
                    sb.append(',');
                }
            }
        }
        return sb.toString();
     }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值