用栈模拟堆盘子

题目:


设想有一堆盘子,堆得太高可能会倒下来,因此,在现实生活中,盘子堆到一定高度时,我们就会另外堆一堆盘子。请实现数据结构SetOfStacks,模拟这种行为。SetOfStacks应该由多个栈组成,并且在一个栈堆满时新建一个栈。

此外,push和pop要和只有一个栈的情况一致。另外需要实现一个popAt(index)方法,根据指定的子栈,执行pop操作,pop之后还要维持栈结构。



代码

package test1;

import java.util.ArrayList;

public class SetOfStacks2 {
    private int HIGHT = 3;
    // 存放已经放满的 stack
    public ArrayList<ArrayList<Integer>> stacks;
    // 当前还在用,没有满的 stack
    public ArrayList<Integer> currStack;

    public SetOfStacks2() {
        stacks = new ArrayList<>();
        currStack = new ArrayList<>();
    }

    public Integer push(Integer item) {
        // 每次push前检查 currStack,如果已经放满,则加入的 stacks,然后新建一个stack
        if (currStack.size() == HIGHT) {
            stacks.add(currStack);
            currStack = new ArrayList<>();
        }
        currStack.add(item);
        return item;
    }

    public Integer pop() {
        return pop(currStack);
    }

    private Integer pop(ArrayList<Integer> theStack) {
        // 每次 pop 之前先检查 currStack是否为空;如果为空,则从stacks中拿一个stack出来
        if (theStack.size() == 0) {
            theStack = stacks.get(stacks.size() - 1);
            stacks.remove(stacks.size() - 1);
        }
        int index = theStack.size() - 1;
        Integer popItem = theStack.get(index);
        theStack.remove(index);
        return popItem;
    }

    /**
     * stack的编号方式是:0,1,……,n,currStack. 在指定编号的stack上做pop操作,然后对后面的stack进行维护,不浪费空间
     */
    public Integer popAt(int index) throws Exception {
        if (index >= stacks.size()) {
            throw new Exception("The index is out of boundary!");
        }

        ArrayList<Integer> theStack = stacks.get(index);
        Integer popItem = pop(theStack);
        int stacksNum = stacks.size();

        ArrayList<Integer> s1, s2;

        for (int i = index; i < stacksNum; i++) {
            s1 = stacks.get(i);
            if (i == stacksNum - 1) {
                s2 = currStack;
                if (currStack.isEmpty()) {
                    currStack = s1;
                    return popItem;
                }
            } else {
                s2 = stacks.get(i + 1);
            }
            move(s1, s2);
        }

        return popItem;
    }

    /**
     * 将s2的底部元素移到s1的顶部
     */
    private boolean move(ArrayList<Integer> s1, ArrayList<Integer> s2) {
        if (s2.isEmpty()) {
            return false;
        }

        s1.add(s2.remove(0));
        return true;
    }

    public void display() {
        int s_stacks = stacks.size();
        System.out.printf("The size of stacks is : %d\n", s_stacks);
        ArrayList<Integer> tmp;
        for (int i = 0; i < s_stacks; i++) {
            tmp = stacks.get(i);
            for (Integer integer : tmp) {
                System.out.printf("%-3s ", integer.toString());
            }
            System.out.print("|| ");
        }
        System.out.printf("\nThe size of current stack is : %d\n", currStack.size());
        for (Integer integer : currStack) {
            System.out.printf("%-3s ", integer.toString());
        }
        System.out.println("\n");
    }
}


测试

    public static void main(String[] args) {
        SetOfStacks2 ss = new SetOfStacks2();
        for (int i = 0; i < 20; i++) {
            ss.push(i);
        }
        ss.display();

        try {
            ss.popAt(2);
            ss.display();

            ss.popAt(3);
            ss.display();

            ss.popAt(2);
            ss.display();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
The size of stacks is : 6
0   1   2   || 3   4   5   || 6   7   8   || 9   10  11  || 12  13  14  || 15  16  17  || 
The size of current stack is : 2
18  19  

The size of stacks is : 6
0   1   2   || 3   4   5   || 6   7   9   || 10  11  12  || 13  14  15  || 16  17  18  || 
The size of current stack is : 1
19  

The size of stacks is : 6
0   1   2   || 3   4   5   || 6   7   9   || 10  11  13  || 14  15  16  || 17  18  19  || 
The size of current stack is : 0


The size of stacks is : 6
0   1   2   || 3   4   5   || 6   7   10  || 11  13  14  || 15  16  17  || 18  19  || 
The size of current stack is : 2
18  19  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值