管理多个堆栈时的问题

issues when managing multiple stacks

研究管理多个堆栈的解决方案,发布问题和我正在调试的代码。问题是,为什么函数 popAt(int index) 从下一个子堆栈的底部移动?是否因为子栈 1 顶部的下一个元素(按入栈顺序)是子栈 2 的底部元素?我不确定这种行为是否正确,以及预期的行为是否是,在弹出堆栈 1 的元素之后,要弹出的下一个元素是堆栈 1 中位于前一个顶部下方的元素,而不是下一个堆栈的底部?

想象一下(字面上的)一堆盘子。如果堆叠太高,它可能会倒塌。因此,在现实生活中,当前一个堆栈超过某个阈值时,我们可能会开始一个新堆栈。模仿这个的数据结构 SetOfStacks。 SetOfStacks 应该由多个堆栈组成,并且应该在前一个堆栈超过容量时创建一个新堆栈。 SetOfStacks.push() 和 SetOfStacks.pop() 应该与单个堆栈的行为相同(也就是说,pop() 应该 return 与只有一个堆栈时的值相同),和函数 popAt(int index) 对特定子堆栈执行弹出操作。

public class SetOfStacks {
    ArrayList<Stack> stacks = new ArrayList<>();
    public int capacity;
    public SetOfStacks(int capacity) {
        this.capacity = capacity;
    }
    public Stack getLastStack() {
        if (stacks.size() == 0) return null;
        return stacks.get(stacks.size() - 1);
    }
    public void push(int v) { /* see earlier code */
    }
    public int pop() {
        Stack last = getLastStack();
        System.out.println(stacks.size());
        int v = last.pop();
        if (last.size == 0) stacks.remove(stacks.size() - 1);
        return v;
    }
    public int popAt(int index) {
        return leftShift(index, true);
    }
    public int leftShift(int index, boolean removeTop) {
        Stack stack = stacks.get(index);
        int removed_item;
        if (removeTop) removed_item = stack.pop();
        else removed_item = stack.removeBottom();
        if (stack.isEmpty()) {
            stacks.remove(index);
        } else if (stacks.size() > index + 1) {
            int v = leftShift(index + 1, false);
            stack.push(v);
        }
        return removed_item;
    }
 }
 public class Stack {
    private int capacity;
    public Node top, bottom;
    public int size = 0;
    public Stack(int capacity) {
        this.capacity = capacity;
    }
    public boolean isAtCapacity() {
        return capacity == size;
    }
    public void join(Node above, Node below) {
        if (below != null) below.above = above;
        if (above != null) above.below = below;
    }
    public boolean push(int v) {
        if (size >= capacity) return false;
        size++;
        Node n = new Node(v);
        if (size == 1) bottom = n;
        join(n, top);
        top = n;
        return true;
    }
    public int pop() {
        Node t = top;
        top = top.below;
        size--;
        return t.value;
    }
    public boolean isEmpty() {
        return size == 0;
    }
    public int removeBottom() {
        Node b = bottom;
        bottom = bottom.above;
        if (bottom != null) bottom.below = null;
        size--;
        return b.value;
    }
 }

提前致谢, 林

leftShift() 在您的代码中可能会随着索引的增加而递归调用,这就是为什么如果您使用索引 1 调用它,它可能会从堆栈 #2 弹出然后(并且,如果所有堆栈的大小都是 1 个元素,它将继续堆栈 #3、#4 等等 :( )

这是我在 java.

中使用 linkedList 对一堆盘子的简单解决方案
class Stack<T>{
Node top;
NodeTop nodeTop;
int count = 1;
int i = 3;
static class Node<T>{
    private T data;
    private Node next;
    Node(T data){
        this.data = data;
        next = null;
    }
}

static class NodeTop<T>{
    private Node<T> top;
    private NodeTop<T> next;
    NodeTop(Node top){
        this.top = top;
    }
}
public void push(T data){
        if(count > i){
            System.out.println("Starting new row of plates");
            NodeTop temp = new NodeTop(top);
            temp.next = nodeTop;
            nodeTop = temp;
            top = null;
            i = i + 3;
        }
        Node temp = new Node(data);
        temp.next = top;
        top = temp;
        count++;
        System.out.println(data);
}

public void pop(){
    if(top == null){
        System.out.println("Current row does not contains any plates, moving to next row");
        if(nodeTop == null){
            System.out.println("No Plates left");
            return;
        }
        top = nodeTop.top;
        nodeTop = nodeTop.next;
        i = i - 3;
    }
    System.out.println(top.data);
    top = top.next;
    count--;
}

}