兩棧共享內存

1 實現原理和步驟

假如存在兩個以數組爲存儲的棧1和棧2,其中棧1已滿了,而棧2還有空間。如果需要繼續往棧1插入數據,則需要棧1重新擴容,即將棧1中數組的數據再複製一遍的另外一個容量更大的棧中,這樣存在空間浪費和效率低的問題。

面對這種場景,可以使用兩棧共享內存的方式,提高空間利用率。開闢一個數組,從位置0開始依次存放棧1的元素,從末端開始存放棧2的元素,每存放一個元素棧指針移動一位,從而提高了空間利用率。當棧1指針的位置 – 棧2指針的位置= 1,說明數組存儲已滿
在這裏插入圖片描述

另外,這種方法也是有缺點,只適合於存儲相同類型的兩個棧

2 完整代碼

package stack;

/**
 * 兩棧共享內存
 * @param <E>
 */
public class DoubleStack <E>{

    /**
     * 使用數組實現棧
     */
    private Object[] elementData;

    /**
     * 棧1頂點的位置
     */
    private int top1;

    /**
     * 棧2頂點的位置
     */
    private int top2;


    /**
     * 有參構造函數
     * @param size
     */
    public DoubleStack(int size){
        elementData = new Object[size];
        top1 = -1;
        top2 = elementData.length;
    }

    /**
     * 插入元素item爲新的棧頂元素
     * @param stackNum 1表示插入棧1,2表示從插入棧2
     * @param item 新元素
     * @return
     */
    public E push(int stackNum, E item) {
        if(top2 - top1 == 1){
            throw new RuntimeException("棧已經滿了!");
        }

        if(stackNum == 1){
            elementData[++top1] = item;
        }else{
            elementData[--top2] = item;
        }

        return item;
    }


    /**
     * 查詢頂元素
     * @param stackNum 1表示插入棧1,2表示從插入棧2
     * @return
     */
    public E peek(int stackNum) {

        if(stackNum == 1){
            if (top1 == -1){
                throw new RuntimeException("棧1爲空!");
            }
            return (E)elementData[top1];
        }else{
            if (top2 == elementData.length){
                throw new RuntimeException("棧2爲空!");
            }
            return (E)elementData[top2];
        }

    }


    /**
     * 彈出堆頂元素
     * @param stackNum 1表示插入棧1,2表示從插入棧2
     * @return
     */
    public  E pop(int stackNum) {
        E obj = null;
        if(stackNum == 1){
            if (top1 == -1){
                throw new RuntimeException("棧1爲空!");
            }

            obj = (E)elementData[top1];
            top1--;
        }else{
            if (top2 == elementData.length){
                throw new RuntimeException("棧2爲空!");
            }

            obj = (E)elementData[top2];
            top2++;
        }

        return obj;
    }

    /**
     * 查看棧是否爲空
     * @param stackNum 1表示插入棧1,2表示從插入棧2
     * @return
     */
    public boolean empty(int stackNum) {
        if(stackNum == 1){
            return top1 == -1;
        }else{
            return top2 == elementData.length;
        }
    }

    /**
     * 遍歷棧
     * @param stackNum 1表示插入棧1,2表示從插入棧2
     * @return
     */
    public String travelsal(int stackNum){
        StringBuilder ret = new StringBuilder("{");

        if (stackNum == 1){
            while (top1 != -1){
                ret.append(pop(1) + ", ");
            }
        }else {
            while (top2 != elementData.length){
                ret.append(pop(2) + ", ");
            }
        }

       return ret.replace(ret.length() - 2, ret.length(), "}").toString();
    }


    /**
     * 測試
     * @param args
     */
    public static void main(String[] args) {
        DoubleStack<String> stack = new DoubleStack<String>(10);
        for (int i = 0; i < 5; i++){
            stack.push(1, "element_" + i );
            stack.push(2, "element_" + (10 - i) );
        }

        System.out.println("棧1的頂元素:" + stack.peek(1));
        System.out.println("棧2的頂元素:" + stack.peek(2));

        System.out.println("遍歷棧1的元素:" + stack.travelsal(1));
        System.out.println("遍歷棧2的元素:" + stack.travelsal(2));


    }
}

3 測試結果

棧1的頂元素:element_4
棧2的頂元素:element_6
遍歷棧1的元素:{element_4, element_3, element_2, element_1, element_0}
遍歷棧2的元素:{element_6, element_7, element_8, element_9, element_10}

4 參考文獻

[1]程傑. 大話數據結構[M]. 清華大學出版社,2011

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章