數據結構之動態數組棧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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章