这可能是一个太容易的问题,但请分享如何扭转任何类型的堆栈?
答案 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)
只需绕过弹出值并将它们推入另一个堆栈。