我有两个堆栈(跟随LIFO)。我想知道我是否可以编写一个C程序来使用这两个堆栈就像一个队列(FIFO)。
答案 0 :(得分:4)
一个堆栈用于将新元素插入队列。另一个堆栈用于删除元素。当输出堆栈为空时,输入堆栈将反转并成为新的输出堆栈。
在伪C中:
typedef struct { stack in, stack out } queue.
void insert(queue *q, void *data) {
push(q->in, data);
}
void* remove(queue *q) {
if (empty(q->out)) {
while (!empty(q->in)) { // q->out = reversed q->in
push(q->out, pop(q->in));
}
}
return pop(q->out); // assumes that it returns NULL if q->out is empty
}
这与常规队列的渐近相同,但每个元素都被触摸了好几次。既然你在C中工作,为什么不使用常规的环形缓冲区?
编辑:这确实是Okasaki的功能排队工作方式,@ bdonlan的答案提到了。
答案 1 :(得分:2)
其中一种技术描述如下:
Chris Okasaki(1995)。简单而有效的纯功能队列和deques。功能编程杂志,5,第583-592页
Fulltext is available in postscript format。这种技术是在函数式编程方面描述的,但没有根本原因可以解释为什么你也不能在C中实现它。
答案 2 :(得分:1)
(为什么不直接使用队列?)
基本上你使用一个堆栈B来反转另一个堆栈B中元素的顺序,方法是弹出A中的所有元素并将它们推入B.当你完成后,你将从B弹出的第一个对象是你推入原始A的第一个。
如果按此顺序将元素1, 2, 3, 4
推送到A中,您将获得:
A: 1, 2, 3, 4 (top)
弹出一切并推进B:
B: 4, 3, 2, 1 (top)
如果你开始弹出B,你会得到顺序:
1, 2, 3, 4
复合操作是类似FIFO的结构。但是,它没有适当FIFO的灵活性,因为它只适用于通过。 可能在低端微控制器的代码中很有用,因为实现堆是一个问题,但你不应该在任何现代(即1980年后)的计算机上使用这样的堆栈。