How to implement a queue with three stacks?

前端 未结 5 1788
忘掉有多难
忘掉有多难 2020-12-12 08:51

I came across this question in an algorithms book (Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne).

Queue with three stacks. Implement

5条回答
  •  醉梦人生
    2020-12-12 09:18

    I am going to attempt a proof to show that it can't be done.


    Suppose there is a queue Q that is simulated by 3 stacks, A, B and C.

    Assertions

    • ASRT0 := Furthermore, assume that Q can simulate operations {queue,dequeue} in O(1). This means that there exists a specific sequence of stack push/pops for every queue/dequeue operation to be simulated.

    • Without loss of generality, assume the queue operations are deterministic.

    Let the elements queued into Q be numbered 1, 2, ..., based on their order of queue, with the first element that is queued into Q being defined as 1, the second one as 2, and so on.

    Define

    • Q(0) := The state of Q when there are 0 elements in Q (and thus 0 elements in A, B and C)
    • Q(1) := The state of Q (and A, B and C) after 1 queue operation on Q(0)
    • Q(n) := The state of Q (and A, B and C) after n queue operations on Q(0)

    Define

    • |Q(n)| := the number of elements in Q(n) (therefore |Q(n)| = n)
    • A(n) := the state of the stack A when the state of Q is Q(n)
    • |A(n)| := the number of elements in A(n)

    And similar definitions for stacks B and C.

    Trivially,

    |Q(n)| = |A(n)| + |B(n)| + |C(n)|
    
    ---
    

    |Q(n)| is obviously unbounded on n.

    Therefore, at least one of |A(n)|, |B(n)| or |C(n)| is unbounded on n.

    WLOG1, suppose stack A is unbounded and stacks B and C are bounded.

    Define * B_u := an upper bound of B * C_u := an upper bound of C * K := B_u + C_u + 1

    WLOG2, for an n such that |A(n)| > K, select K elements from Q(n). Suppose that 1 of those elements is in A(n + x), for all x >= 0, i.e. the element is always in stack A no matter how many queue operations are done.

    • X := that element

    Then we can define

    • Abv(n) := the number of items in stack A(n) that is above X
    • Blo(n) := the number of elements in stack A(n) that is below X

      |A(n)| = Abv(n) + Blo(n)

    ASRT1 := The number of pops required to dequeue X from Q(n) is at least Abv(n)

    From (ASRT0) and (ASRT1), ASRT2 := Abv(n) must be bounded.

    If Abv(n) is unbounded, then if 20 dequeues are required to dequeue X from Q(n), it will require at least Abv(n)/20 pops. Which is unbounded. 20 can be any constant.

    Therefore,

    ASRT3 := Blo(n) = |A(n)| - Abv(n)
    

    must be unbounded.


    WLOG3, we can select the K elements from the bottom of A(n), and one of them is in A(n + x) for all x >= 0

    X(n) := that element, for any given n

    ASRT4 := Abv(n) >= |A(n)| - K
    

    Whenever an element is queued into Q(n)...

    WLOG4, suppose B and C are already filled to their upper bounds. Suppose that the upper bound for elements above X(n) has been reached. Then, a new element enters A.

    WLOG5, suppose that as a result, the new element must enter below X(n).

    ASRT5 := The number of pops required to put an element below X(n) >= Abv(X(n))

    From (ASRT4), Abv(n) is unbounded on n.

    Therefore, the number of pops required to put an element below X(n) is unbounded.


    This contradicts ASRT1, therefore, it is not possible to simulate an O(1) queue with 3 stacks.


    I.e.

    At least 1 stack must be unbounded.

    For an element that stays in that stack, the number of elements above it must be bounded, or the dequeue operation to remove that element will be unbounded.

    However, if the number of elements above it is bounded, then it will reach a limit. At some point, a new element must enter below it.

    Since we can always choose the old element from among one of the lowest few elements of that stack, there can be an unbounded number of elements above it (based on the unbounded size of the unbounded stack).

    To enter a new element below it, since there's an unbounded number of elements above it, an unbounded number of pops is required to put the new element below it.

    And thus the contradiction.


    There are 5 WLOG (Without loss of generality) statements. In some sense, they can be intuitively understood to be true (but given that they are 5, it might take some time). The formal proof that no generality is lost can be derived, but is extremely lengthy. They're omitted.

    I do admit that such omission might leave the WLOG statements in question. With a programmer's paranoia for bugs, please do verify the WLOG statements if you like to.

    The third stack is also irrelevant. What matters is that there's a set of bounded stacks, and a set of unbounded stacks. The minimum needed for an example is 2 stacks. The number of stacks must be, of course, finite.

    Lastly, if I am right that there's no proof, then there should be an easier inductive proof available. Probably based on what happens after every queue (keep track of how it affects the worst case of dequeue given the set of all elements in the queue).

提交回复
热议问题