Created
January 5, 2024 06:35
-
-
Save yanfeng42/feb4df6c1b2817133e29de94ec5f5c45 to your computer and use it in GitHub Desktop.
1.3.49栈与队列。用有限个栈实现一个队列,保证每个队列操作(在最坏的情况下)都只需要常数次的栈操作。警告:非常难!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package study.algorithm; | |
import edu.princeton.cs.algs4.StdOut; | |
public class QueueFromSevenStack<Item> { | |
private boolean isRevert = false; // 是否在反转 Stack. | |
private boolean isConcat = false; // 是否在拼接 Stack. | |
private Stack<Item> T = new Stack<>(); // 队列尾部,用于 enqueue 入队操作. | |
private Stack<Item> H = new Stack<>(); // 队列头部, 用于 dequeue 出队操作. | |
private Stack<Item> TS = new Stack<>(); // 暂存 T 中的数据. | |
private Stack<Item> TR = new Stack<>(); // T 反转后的数据,后续会拼接 HR 中的元素. | |
private Stack<Item> TRC = new Stack<>(); // TR 的副本, 与T中元素完全一致. | |
private Stack<Item> HR = new Stack<>(); // H 反转后的数据. | |
private Stack<Item> HC = new Stack<>(); // H 的副本, 初始与H中的元素完全一致. | |
private Integer dequeueItemCount = 0; // 在 反转或拼接Stack过程中, 出队的元素数量. | |
public void enqueue(Item item) { | |
T.push(item); | |
process(true); | |
} | |
public Item dequeue() { | |
if(H.isEmpty()){ | |
return null; | |
} | |
Item item = H.pop(); | |
process(false); | |
return item; | |
} | |
private void process(Boolean isEnqueue) { | |
if(!isEnqueue){ | |
if(isRevert || isConcat){ | |
dequeueItemCount += 1; | |
} else { | |
// 一种特殊情况: 仅存在 dequeue 操作时,直接 pop H的副本, 不用额外计数. | |
HC.pop(); | |
} | |
} | |
if (!isRevert && !isConcat && !T.isEmpty() && T.size() >= H.size()) { | |
// 仅在必要时进入 Revert Stack阶段. | |
TS = T; | |
T = new Stack<>(); | |
isRevert = true; | |
} | |
if (isRevert) { | |
if (!TS.isEmpty()) { | |
Item item = TS.pop(); | |
TR.push(item); | |
TRC.push(item); | |
} | |
if (!HC.isEmpty()) { | |
Item item = HC.pop(); | |
HR.push(item); | |
} | |
} | |
if (TS.isEmpty() && HC.isEmpty()) { | |
isRevert = false; | |
isConcat = true; | |
} | |
if (isConcat) { | |
if (!HR.isEmpty() && HR.size() > dequeueItemCount) { | |
Item item = HR.pop(); | |
TR.push(item); | |
TRC.push(item); | |
} | |
if (HR.isEmpty() || HR.size() == dequeueItemCount) { | |
H = TR; | |
HC = TRC; | |
TR = new Stack<>(); | |
TRC = new Stack<>(); | |
HR = new Stack<>(); | |
isConcat = false; | |
dequeueItemCount = 0; | |
} | |
} | |
} | |
public static void main(String[] args) { | |
QueueFromSevenStack<Integer> q = new QueueFromSevenStack<>(); | |
StdOut.println("enqueue 0"); | |
q.enqueue(0); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("enqueue 1"); | |
q.enqueue(1); | |
StdOut.println("enqueue 2~3"); | |
q.enqueue(2); | |
q.enqueue(3); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("enqueue 4 ~ 6"); | |
q.enqueue(4); | |
q.enqueue(5); | |
q.enqueue(6); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("enqueue 7 ~ 10"); | |
q.enqueue(7); | |
q.enqueue(8); | |
q.enqueue(9); | |
q.enqueue(10); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
StdOut.println("dequeue: " + q.dequeue()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment