一、題目:用兩個棧實現隊列
題目:用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數appendTail和deleteHead,分別完成在隊列尾部插入結點和在隊列頭部刪除結點的功能。

原文是使用C++結合模板實現的定義,這里我們采用C#結合泛型來實現這個隊列的定義,我們要實現的就是兩個方法:AppendTail與DeleteHead
public class CQueue<T> { private Stack<T> stack1; private Stack<T> stack2; public CQueue() { this.stack1 = new Stack<T>(); this.stack2 = new Stack<T>(); } public void AppendTail(T item) { } public T DeleteHead() { } }
二、解題思路
一個隊列包含了兩個棧stack1和stack2,因此這道題的意圖是要求我們操作這兩個“先進后出”的棧實現一個“先進先出”的隊列CQueue。對於兩個棧而言,對於插入操作,不妨假設都先插入到stack1,也就實現了入隊操作。但是出隊操作,則需要借助stack2的過渡:
當stack2中不為空時,在stack2中的棧頂元素是最先進入隊列的元素,可以彈出。如果stack2為空時,我們把stack1中的元素逐個彈出並壓入stack2。由於先進入隊列的元素被壓到stack1的底端,經過彈出和壓入之后就處於stack2的頂端了,又可以直接彈出。下圖展示了一個使用兩個棧實現隊列的實例:

三、解決問題
3.1 代碼實現
public void AppendTail(T item) { stack1.Push(item); } public T DeleteHead() { if(stack2.Count <= 0) { while(stack1.Count > 0) { T item = stack1.Pop(); stack2.Push(item); } } if(stack2.Count == 0) { throw new Exception("The queue is empty!"); } T head = stack2.Pop(); return head; }
借用作者的話:本題解法的代碼雖然只有只有20幾行代碼,但形成正確的思路卻不容易。
3.2 單元測試
(1)往空的隊列里添加、刪除元素
[TestMethod] public void CQueueTest1() { CQueue<char> queue = new CQueue<char>(); queue.AppendTail('a'); queue.AppendTail('b'); queue.AppendTail('c'); char head = queue.DeleteHead(); Assert.AreEqual(head, 'a'); } [TestMethod] public void CQueueTest2() { CQueue<char> queue = new CQueue<char>(); queue.AppendTail('a'); queue.AppendTail('b'); queue.AppendTail('c'); char head = queue.DeleteHead(); head = queue.DeleteHead(); Assert.AreEqual(head, 'b'); }
(2)往非空的隊列里添加、刪除元素
[TestMethod] public void CQueueTest3() { CQueue<char> queue = new CQueue<char>(); queue.AppendTail('a'); queue.AppendTail('b'); queue.AppendTail('c'); char head = queue.DeleteHead(); head = queue.DeleteHead(); queue.AppendTail('d'); head = queue.DeleteHead(); Assert.AreEqual(head, 'c'); } [TestMethod] public void CQueueTest4() { CQueue<char> queue = new CQueue<char>(); queue.AppendTail('a'); queue.AppendTail('b'); queue.AppendTail('c'); char head = queue.DeleteHead(); head = queue.DeleteHead(); queue.AppendTail('d'); head = queue.DeleteHead(); queue.AppendTail('e'); head = queue.DeleteHead(); Assert.AreEqual(head, 'd'); }
(3)連續刪除元素直至隊列為空
[TestMethod] public void CQueueTest5() { CQueue<char> queue = new CQueue<char>(); queue.AppendTail('a'); queue.AppendTail('b'); queue.AppendTail('c'); char head = queue.DeleteHead(); head = queue.DeleteHead(); queue.AppendTail('d'); head = queue.DeleteHead(); queue.AppendTail('e'); head = queue.DeleteHead(); head = queue.DeleteHead(); Assert.AreEqual(head, 'e'); }
單元測試的結果如下圖所示:

代碼覆蓋率結果如下圖所示,可以看到,還需要繼續增加測試用例才能使得覆蓋率達到100%:

