用栈模拟堆盘子
2016-04-20 02:18
211 查看
题目:
设想有一堆盘子,堆得太高可能会倒下来,因此,在现实生活中,盘子堆到一定高度时,我们就会另外堆一堆盘子。请实现数据结构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
相关文章推荐
- C++基于栈实现铁轨问题
- C语言栈的表示与实现实例详解
- C语言实现颠倒栈的方法
- 算法系列15天速成 第十天 栈
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- Array栈方法和队列方法的特点说明
- java数据结构之java实现栈
- 浅析栈区和堆区内存分配的区别
- 用Java代码实现栈数据结构的基本方法归纳
- 用PHP解决的一个栈的面试题
- 浅谈C#中堆和栈的区别(附上图解)
- JavaScript数据结构与算法之栈详解
- C语言之栈和堆(Stack && Heap)的优缺点及其使用区别
- Python实现栈的方法
- JavaScript数据结构与算法之栈与队列
- JavaScipt中栈的实现方法
- Java中堆和栈的区别详解
- 详解Java的堆内存与栈内存的存储机制
- java中堆和栈的区别分析
- C/C++函数调用栈的实现方法