使用LIFO实现FIFO

时间:2012-03-12 08:08:41

标签: algorithm fifo

在网上看一些算法练习,我发现了一个有趣的算法:

如何使用LIFO实现FIFO?

我尝试了自己,但我最终只得到了一个解决方案:每次我们想要FIFO的元素时,将lifo复制到另一个lifo(不包括最后一个元素获取正面元素并将其移除,然后将第二个LIFO复制回第一个LIFO。

但这当然非常慢,它就是这样一个简单的循环:

for(!myfifo.empty()) {
  myfifo.pop();
}

在标准的FIFO实现上 O(n²)而不是 O(n)

当然,LIFO不会做FIFO而我们通过使用基于LIFO的“原生”FIFO和假FIFO也不一定会有相同的复杂性,但我认为肯定有一种做法比O(n²)好。有没有人对此有所了解?

提前致谢。

2 个答案:

答案 0 :(得分:13)

使用2个LIFO [堆栈],每个OP FIFO [队列]可以获得amortized time complexityO(1)

假设您有stack1stack2

insert(e):
   stack1.push(e)

take():
   if (stack2.empty()):
      while (stack1.empty() == false):
            stack2.push(stack1.pop())
   return stack2.pop() //assume stack2.pop() handles empty stack already

示例:

push(1)

|1|  | |
|-|  |-|

push(2)
|2|  | |
|1|  | |
|-|  |-|

pop()
push 2 to stack2 and pop it from stack1:
|1|  |2|
|-|  |-|
push 1 to stack2 and pop it from stack2:
| |  |1|
| |  |2|
|-|  |-|
pop1 from stack2 and return it:
| |  |2|
|-|  |-|

要获得真实的O(1) [未摊销],它要复杂得多,需要更多堆叠,请查看this post

中的一些答案

编辑:复杂性分析:

  1. 每个insert()都是trivaially O(1) [只是推到stack1]
  2. 请注意,每个元素最多push()次,pop()最多两次,一次来自stack1,另一次来自stack2。由于没有其他操作,对于n元素,我们最多只有2n push()2n pop() s,这最多给了我们4n * O(1)复杂度[因为pop()push()都是O(1)],O(n) - 我们得到的摊销时间为:O(1) * 4n / n = O(1)

答案 1 :(得分:1)

LIFO和FIFO都可以用数组实现,它们之间的唯一区别在于 tail head 指针的工作方式。假设你从LIFO开始,你可以添加两个额外的指针来反映FIFO的尾部和头部,然后使用FIFO指针添加方法添加,删除等等。

输出类型与专用FIFO或LIFO类型一样快,但它同时支持两者。您需要使用独特的类型成员,例如AddToStack / AddToQueue,RemoveFromStack / RemoveFromQueue等。