如何反转堆栈?

时间:2011-03-22 16:31:11

标签: algorithm scala stack

这可能是一个太容易的问题,但请分享如何扭转任何类型的堆栈?

5 个答案:

答案 0 :(得分:12)

正确答案可能是“不要反转堆栈。”

如果某些约束意味着您必须反转堆栈,则您的问题已经得到解答。但是,我不禁想知道为什么你要反转堆栈 - 对我来说,这意味着你使用了错误的数据结构。

如果它全部推动,那么相反,然后所有的弹出;这就是一个队列。

如果推送,弹出和反转以随机顺序混合,您可能需要一个专门支持这些操作的数据结构......当有人读取“堆栈”但结构确实是其他内容时,它会让人感到困惑。

不确定scala,但有些语言有一个双端队列来专门代表一个线性集合,可以访问head和tail元素 - 这可能正是你所需要的。如果没有,双重链表就会很好;如果O(n)pop() - 等价物不是问题,那么普通旧列表就会发生。

如果你的pop()等效操作不知道从哪一端获取元素(例如,一段代码正在调用reverse,而其他一些代码只是说“给我一个元素”并且isn'知道是否已经调用了反向),使用方向标志封装队列,如下所示。这将为您提供相同的功能,而无需实际转换任何内容。

(抱歉非常伪代码,scala不在我的工具箱中)。

ReversableStack {
    DoublyLinkedList backingStore;
    Boolean forward;

    get() {
        if (forward) return backingStore.take_head();
        else return backingStore.take_tail();
    }

    put(item) {
        if (forward) backingStore.add_head(item);
        else backingStore.add_tail(item);
    }

    reverse() {
        forward = !forward;
    }
}

答案 1 :(得分:8)

make new stack;
while (old stack not empty)
    x = pop(old stack)
    push x on new stack

或者在堆栈上调用reverse,但请注意,如果应用于List,则会返回mutable.Stack。如果您使用Stack,它会返回immutable.Stack

答案 2 :(得分:6)

答案 3 :(得分:2)

public void reverse(Stack st) { 
    int m = (int)st.Pop(); 
    if (st.Count != 1) 
        reverse(st); 
    Push(st , m); 
} 

public void Push(Stack st , int a) { 
    int m = (int)st.Pop(); 
    if (st.Count != 0) 
        Push(st , a); 
    else 
        st.Push(a); 
    st.Push(m); 
}

答案 4 :(得分:1)

只需绕过弹出值并将它们推入另一个堆栈。