佇列和棧的轉換
阿新 • • 發佈:2018-11-11
1. 兩個棧實現佇列
//前提已知: struct Stack { int top; //棧頂指標 int stacksize;//棧的大小 int *s; //棧底指標 }; void InitStack(Stack *s); void Push(Stack *s, int k); int Pop(*s); int IsStackEmpty(*s); int IsStackFull(*s);
實現一
思路
s1是入棧的,s2是出棧的。
- 入佇列,直接壓到s1是就行了
- 出佇列,先把s1中的元素全部出棧壓入到s2中,彈出s2中的棧頂元素;再把s2的所有元素全部壓回s1中
實現二
思路
s1是入棧的,s2是出棧的。保證所有元素都在一個棧裡面
- 入佇列時:如果s1為空,把s2中所有的元素倒出壓到s1中;否則直接壓入s1
- 出佇列時:如果s2不為空,把s2中的棧頂元素直接彈出;否則,把s1的所有元素全部彈出壓入s2中,再彈出s2的棧頂元素
比較:與實現一相比較,出佇列時不必每次都搗鼓了。
實現三
思路
s1是入棧的,s2是出棧的。
- 入佇列:直接壓入s1即可
- 出佇列:如果s2不為空,把s2中的棧頂元素直接彈出;否則,把s1的所有元素全部彈出壓入s2中,再彈出s2的棧頂元素
比較
與實現二相比較,入隊直接入即可,感覺此時已是最優。
參考程式碼
void EnQueue(Stack *s1, Stack *s2, int k) { Push(s1, k); } int DeQueue(Stack *s1, Stack*s2) { if(IsStackEmpty(s2) == 1) { while(IsStackEmpty(s1) == 0) { Push(s2, Pop(s1)); } } if(IsStackEmpty(s2) == 1) { printf("Empty!\n"); } return Pop(s2);
2. 兩個佇列實現棧
//前提已知 typedef struct queue { int queuesize; int head, tail; int *q; }Queue; void InitQueue(Queue *q); void EnQueue(Queue *q, int key); int DeQueue(Queue *q); int SizeOfQueue(Queue *q); int IsQueueEmpty(Queue *q); int IsQueueFull(Queue *q);
實現一
思路
q1是專職進出棧的,q2只是箇中轉站
- 入棧:直接入佇列q1即可
- 出棧:把q1的除最後一個元素外全部轉移到隊q2中,然後把剛才剩下q1中的那個元素出佇列。之後把q2中的全部元素轉移回q1中
圖示
參考程式碼
void Push(Queue *q1, Queue *q2, int k) { EnQueue(q1, k); } int Pop(Queue *q1, Queue *q2) { int tmp; if(IsQueueEmpty(q1) == 1) { printf("Stack Empty!\n"); } else { while(SizeOfQueue(q1) != 1) { EnQueue(q2, DeQueue(q1)); } tmp = DeQueue(q1); while(IsQueueEmpty(q2) == 0) { EnQueue(q1, DeQueue(q2)); } return tmp; } }
實現二
思路
q1是專職進出棧的,q2只是箇中轉站。元素集中存放在一個棧中,但不是指定(q1 或 q2)。
定義兩個指標:pushtmp:指向專門進棧的佇列q1; tmp:指向臨時作為中轉站的另一個棧q2
- 入棧:直接入pushtmp所指佇列即可
- 出棧:把pushtmp的除最後一個元素外全部轉移到佇列tmp中,然後把剛才剩下q1中的那個元素出佇列
比較
實現二,出棧後就不用轉移回原來的棧了(圖示最後一步),這樣減少了轉移的次數。
參考程式碼
void Push(Queue *q1, Queue *q2, int k) { Queue *pushtmp; if(!IsQueueEmpty(q1)) { pushtmp = q1; } else { pushtmp = q2; } EnQueue(pushtmp, k); } int Pop(Queue *q1, Queue *q2) { int tmpvalue; Queue *pushtmp, *tmp; if(!IsQueueEmpty(q1)) { pushtmp = q1; tmp = q2; } else { pushtmp = q2; tmp = q1; } if(IsQueueEmpty(pushtmp)) { printf("Stack Empty!\n"); } else { while(SizeOfQueue(pushtmp) != 1) { EnQueue(tmp, DeQueue(pushtmp)); } tmpvalue = DeQueue(pushtmp); return tmpvalue; } }