1. 程式人生 > 其它 >用兩個棧實現佇列 / 模板

用兩個棧實現佇列 / 模板

技術標籤:劍指Offer

用兩個棧實現一個佇列。佇列的宣告如下,請實現它的兩個函式 appendTail 和 deleteHead ,分別完成在佇列尾部插入整數和在佇列頭部刪除整數的功能。(若佇列中沒有元素,deleteHead 操作返回 -1 )

一開始考慮的時候:兩個棧,肯定一個用作入隊,一個用作出隊,於是會有下面這樣的程式碼:

class CQueue {

    private Stack<Integer> s1;
    private Stack<Integer> s2;

    public CQueue() {
        s1 = new
Stack<>(); s2 = new Stack<>(); } public void appendTail(int value) { s1.add(value); } public int deleteHead() { if (s1.isEmpty()) { return -1; } while (!s1.isEmpty()) { s2.add(s1.peek()); s1.pop
(); } int rec = s2.peek(); s2.pop(); while (!s2.isEmpty()) { s1.add(s2.peek()); s2.pop(); } return rec; } }

在這裡插入圖片描述
emmm,時間看似不太行… 有一個很明顯的問題:如果是連續出隊的話,兩個棧之間元素的複製步驟將有很大一部分是重複的。事實上,如果以stack1為入隊用,stack2為出隊用,那麼stack2不為空的時候,直接返回隊頭元素,這樣的做法才是高效的。

class CQueue {

    private Stack<Integer> s1;
    private Stack<Integer> s2;

    public CQueue() {
        s1 = new Stack<>();
        s2 = new Stack<>();
    }

    public void appendTail(int value) {
        s1.add(value);
    }

    public int deleteHead() {
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.add(s1.peek());
                s1.pop();
            }
        }
        // s2還是空的,那麼說明佇列中沒有任何元素
        if (s2.isEmpty()) {
            return -1;
        }
        int rec = s2.peek();
        s2.pop();
        return rec;
    }
}

在這裡插入圖片描述
這樣子就差不多了。

這道題在《劍指Offer》中,本意還是要我們用模板實現,這裡我們簡單複習一下C++和Java的模板寫法。

函式模板示例 (C++)

#include <iostream>
using namespace std;

template<typename T>
inline T const& Max(T const& a, T const& b) {
    return a < b ? b : a;
}

int main() {
    cout << Max(1, 2) << endl;
    cout << Max('a', 'b') << endl;
    getchar();
    return 0;
}

類模板示例 (C++)

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
 
using namespace std;
 
template <class T>
class Stack { 
  private: 
    vector<T> elems;     // 元素 
 
  public: 
    void push(T const&);  // 入棧
    void pop();               // 出棧
    T top() const;            // 返回棧頂元素
    bool empty() const{       // 如果為空則返回真。
        return elems.empty(); 
    } 
}; 
 
template <class T>
void Stack<T>::push (T const& elem) 
{ 
    // 追加傳入元素的副本
    elems.push_back(elem);    
} 
 
template <class T>
void Stack<T>::pop () 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::pop(): empty stack"); 
    }
    // 刪除最後一個元素
    elems.pop_back();         
} 
 
template <class T>
T Stack<T>::top () const 
{ 
    if (elems.empty()) { 
        throw out_of_range("Stack<>::top(): empty stack"); 
    }
    // 返回最後一個元素的副本 
    return elems.back();      
} 
 
int main() 
{ 
    try { 
        Stack<int>         intStack;  // int 型別的棧 
        Stack<string> stringStack;    // string 型別的棧 
 
        // 操作 int 型別的棧 
        intStack.push(7); 
        cout << intStack.top() <<endl; 
 
        // 操作 string 型別的棧 
        stringStack.push("hello"); 
        cout << stringStack.top() << std::endl; 
        stringStack.pop(); 
        stringStack.pop(); 
        getchar();
    } 
    catch (exception const& ex) { 
        cerr << "Exception: " << ex.what() <<endl; 
        getchar();
        return -1;
    } 
}

模板類和模板方法 (Java)

class vectorElement<T>{
 
	public vectorElement<T> next=null;
	public vectorElement<T> previous=null;
	public T datum=null;
 
	public vectorElement(T datum){ this.datum=datum; }
 
}