您的位置:首页 > 运维架构

用栈模拟堆盘子

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆盘子 popAt-int