数据结构之动态数组栈Stack

1)栈的定义

栈是限定仅在表尾进行插入和删除操作的线性表

  • 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
  • 不含任何数据元素的栈称为空栈
  • 栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构
  • 栈本身是一个线性表,其数据元素具有线性关系,只不过它是一种特殊的线性表而已
  • 定义中说的是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底
  • 栈的插入操作,叫作进栈,也称压栈、入栈
  • 栈的删除操作,叫作出栈,也称弹栈
    在这里插入图片描述2)栈接口Stack的定义
    在这里插入图片描述
public interface Stack<E> extends Iterable<E>{
    //获取栈中元素个数
    int getSize();
    //是否为空
    boolean isEmpty();
    //进栈
    void push(E e);
    //出栈
    E pop();
    //查看栈
    E peek();
    //清空
    void clear();
}

3)栈的顺序存储结构ArrayStack的定义
在这里插入图片描述

import java.util.Iterator;

public class ArrayStack<E> implements Stack<E>{
    private ArrayList<E> list;

    //创建一个默认大小的栈
    public ArrayStack(){
        list=new ArrayList<>();
    }
    //创建一个指定大小的栈
    public ArrayStack(int capacity){
        list =new ArrayList<E>(capacity);
    }

    @Override
    public int getSize(){
        return list.getSize();
    }

    @Override
    public boolean isEmpty(){
        return list.isEmpty();
    }

    @Override
    public void push(E e){
        list.addLast(e);
    }

    @Override
    public E pop(){
        return list.removeLast();
    }

    @Override
    public E peek(){
        return list.getLast();
    }
    //清空
    public void clear(){
        list.clear();
    }

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

4)双端栈的定义

是指将一个线性表的两端当做栈底分别进行入栈和出栈操作
在这里插入图片描述5)双端栈的顺序存储结构ArrayStackDoubleEnd的定义
在这里插入图片描述

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;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值