数据结构(双端栈的顺序存储结构)

双端栈的定义
是指将一个线性表的两端当做栈底分别进行入栈和出栈操作
在这里插入图片描述
具体实现

package DS01.动态数组;
/*
线性表的一种特殊情况 栈
ArrayStack extends ArrayList
ArrayList当做是ArraySatck的一个成员变量
*/
public interface Stack<E> extends Iterable<E>{
    //获取栈中元素的个数
    int getSize();
    //判断栈是否为空
    boolean isEmpty();
    //将元素e进栈
    void push(E e);
    //弹栈一个元素并返回
    E pop();
    //查看当前栈顶元素
    E peek();
    //清空栈
    void clear();
}

package DS01.动态数组;

import java.util.Iterator;

/*
* 双端栈
* */
public class ArrayStackDoubleEnd<E> implements Stack<E>{
    private static final int DEFAULT_SIZE=10;
    private E[] data;
    private int leftTop;
    private int rightTop;

    public ArrayStackDoubleEnd(){
        this(DEFAULT_SIZE);
    }
    public ArrayStackDoubleEnd(int capacity){
        data=(E[])(new Object[capacity]);
        leftTop=-1;
        rightTop=data.length;
    }
    //获取左栈中有效元素个数
    public int getLeftSize(){
        return leftTop+1;
    }
    //获取右栈中有效元素个数
    public int getRightSize(){
        return data.length-rightTop;
    }
    //获取栈中所有元素的个数
    @Override
    public int getSize() {
        return getLeftSize()+getRightSize();
    }

    //判断左栈是否为空
    public boolean isLeftEmpty(){
        return leftTop==-1;
    }
    //判断右栈是否为空
    public boolean isRightEmpty(){
        return rightTop==data.length;
    }
    //判断栈是否为空
    @Override
    public boolean isEmpty() {
        return isLeftEmpty()&&isRightEmpty();
    }

    //在左栈进栈
    public void pushLeft(E e){
        //满了扩容
        if(leftTop+1==rightTop){
            resize(2*data.length);
        }
        leftTop++;
        data[leftTop]=e;
    }
    //在右栈进栈
    public void pushRight(E e){
        if(rightTop-1==leftTop){
            resize(2*data.length);
        }
        rightTop--;
        data[rightTop]=e;
    }
    private void resize(int newLen){
        E[] newData=(E[])(new Object[newLen]);
        //扩容和缩容时左边的复制
        for(int i=0;i<=leftTop;i++){
            newData[i]=data[i];
        }
        //扩容时右边的复制
        if(newData.length>data.length){
            for(int i=rightTop;i<data.length;i++){
                newData[i+data.length]=data[i];
            }
            rightTop=rightTop+data.length;
        }else{//缩容时右边的复制
            for(int i=rightTop;i<data.length;i++){
                newData[i-newData.length]=data[i];
            }
            rightTop=rightTop-newData.length;
        }

        data=newData;
    }
    //进栈元素e
    @Override
    public void push(E e) {
        if(getLeftSize()<=getRightSize()){
            pushLeft(e);
        }else{
            pushRight(e);
        }
    }

    public E popLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("左栈为空");
        }
        E ret=data[leftTop--];

        if(getSize()<=data.length/4&&data.length/2>10){
            resize(data.length/2);
        }

        return ret;
    }
    public E popRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("右栈为空");
        }
        E ret=data[rightTop++];
        if(getSize()<=data.length/4&&data.length/2>=10){
            resize(data.length/2);
        }
        return ret;
    }
    @Override
    public E pop() {
        if(getLeftSize()>=getRightSize()){
            return popLeft();
        }else{
            return popRight();
        }
    }

    public E peekLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("左栈为空");
        }
        return data[leftTop];
    }
    public E peekRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("右栈为空");
        }
        return data[rightTop];
    }
    @Override
    public E peek() {
        if(getLeftSize()>=getRightSize()){
            return peekLeft();
        }else{
            return peekRight();
        }
    }

    @Override
    public void clear() {
        data= (E[]) new Object[DEFAULT_SIZE];
        leftTop=-1;
        rightTop=data.length;
    }

    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        sb.append(String.format("ArrayStackDoubleEnd: %d/%d\n",getSize(),data.length));
        if(isLeftEmpty()){
            sb.append("left :bottom [] top");
        }else{
            sb.append("left :bottom [");
            for(int i=0;i<=leftTop;i++){
                sb.append(data[i]);
                if(i==leftTop){
                    sb.append("] top");
                }else{
                    sb.append(',');
                }
            }
        }
        sb.append('\n');
        if(isRightEmpty()){
            sb.append("right:top [] bootom\n");
        }else {
            sb.append("right:top [");
            for(int i=rightTop;i<data.length;i++){
                sb.append(data[i]);
                if(i==data.length-1){
                    sb.append("] bottom");
                }else{
                    sb.append(',');
                }
            }
        }
        return sb.toString();
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }
}

测试类

package DS01.动态数组;

public class TestArrayStackDoubleEnd {
    public static void main(String[] args) {
        ArrayStackDoubleEnd<Integer> stack=new ArrayStackDoubleEnd<>();
        System.out.println(stack);
        for(int i=1;i<=6;i++){
            stack.pushLeft(i);
        }
        for(int i=1;i<=6;i++){
            stack.pushRight(i);
        }
        System.out.println(stack);

        for(int i=1;i<=8;i++){
            System.out.print(stack.pop()+" ");
        }
        System.out.println();
        System.out.println(stack);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值