Looking at some algorithm exercices on the net, I found an interesting one :
How would you implement a FIFO using a LIFO ?
I tried myself but I ended up with only one solution : each time we want the front element of the FIFO, copy the lifo into another lifo (excluding last element, which is the front), get the front element and remove it, then copy back the second LIFO into the first LIFO.
But this is of course horribly slow, it makes a simple loop like this :
for(!myfifo.empty()) {
myfifo.pop();
}
going O(n²) instead of O(n) on a standard implementation of the FIFO.
Of course, LIFO are not made to do FIFO and we won't certainly have the same complexity by using a "native" FIFO and a fake-FIFO based on a LIFO, but I think there is certainly a way of doing better than O(n²). Has anyone an idea about that ?
Thanks in advance.
You can get amortized time complexity of O(1)
per OP FIFO [queue] using 2 LIFOs [stacks].
Assume you have stack1
, stack2
:
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
example:
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|
|-| |-|
To get real O(1)
[not amortized], it is much more complicated and requires more stacks, have a look at some of the answers in this post
EDIT: Complexity analysis:
insert()
is trivaially O(1)
[just pushing it to stack1
]push()
ed and pop()
ed at most twice, once from stack1
and once from stack2
. Since there is no more ops then these, for n
elements, we have at most 2n
push()
s and 2n
pop()
s, which gives us at most 4n * O(1)
complexity [since both pop()
and push()
are O(1)
], which is O(n)
- and we get amortized time of: O(1) * 4n / n = O(1)