两栈共享内存

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

原创文章 32 获赞 12 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_35469756/article/details/99667245
今日推荐