在前面的小節裡已經實現了queue,當時所採用的是front和rear兩個指標分別指向隊頭和隊尾。由於本題限制,不能使用這些指標。
如何只使用stack實現queue呢?由於stack是現進後出(FILO),而queue是先進先出的(FIFO)。也就是說stack進行了一次反向,進行兩次反向就能實現queue的功能,所以可以用兩個stack實現queue。
假設兩個棧A和B,且都為空白。可以認為棧A提供入隊的功能,棧B提供出隊的功能。下面是入隊和出隊的具體演算法:
(1)如果棧B不為空白,直接彈出棧B的資料。
(2)如果棧B為空白,則依次彈出棧A的資料,放入棧B中,再彈出棧B的資料。
於是可以得到下面MyQueue定義及實現:(其中使用的MyData 和 MyStack 是前一章的內容)
class MyQueue{public:void enqueue(MyData data);//入隊void dequeue(MyData &data);//出隊bool IsEmpty();//判空private:MyStack s1;//用於入隊MyStack s2;//用於出隊};//入隊void MyQueue::enqueue(MyData data){s1.push(data);//只對s1進行進棧操作}//出隊void MyQueue::dequeue(MyData &data){MyData temp(0);//局部變數,用於臨時儲存if(s2.IsEmpty()){while(! s1.IsEmpty()){//如果s2為空白,把s1的所有元素push到s2中s1.pop(&temp);//彈出s1的元素s2.push(temp);//壓入s2中}}if(!s2.IsEmpty()){//此時如果s2不為空白,彈出s2的棧頂元素s2.pop(&data);}}//隊列判空bool MyQueue::IsEmpty(){//如果兩個棧都為空白,則返回1,否則返回0return (s1.IsEmpty() && s2.IsEmpty());}
下面是測試程式:
int main(){MyData data(0);MyQueue q;q.enqueue(MyData(1)); //進隊順序 1、2、3q.enqueue(MyData(2));q.enqueue(MyData(3));q.dequeue(data);cout<<"dequeue "<<data.data<<endl;q.dequeue(data);cout<<"dequeue "<<data.data<<endl;q.dequeue(data);cout<<"dequeue "<<data.data<<endl;cout<<"Empty = "<<q.IsEmpty()<<endl;return 0;}
執行結果:
dequeue 1 //出隊列順序 1、2、3dequeue 2dequeue 3Empty = 1Press any key to continue