棧和隊列的比較ios
棧和隊列都屬於線性表,且在其上進行Insert和Delete操做所插入和移除的元素是預先設定的。在棧中,在一端插入,在同一端刪除,位於該端點的元素稱爲棧頂元素;在隊列中,在一端插入,在另外一端刪除,位於兩端點的元素分別稱爲隊列尾和隊列頭。數組
因此在棧的實現中,須要記錄的變量是棧頂元素位置;而在隊列的實現中,須要記錄的變量有隊列頭和隊列尾的位置。this
用數組實現一個棧spa
都須要記錄哪些信息?棧頂元素下標index,以及數組自己的指針p、總長度MAX_SIZE。指針
棧頂元素下標index與其對應的數組元素下標f(index)之間的映射關係是怎樣的?隨着棧的增加,棧頂元素下標依次爲0,1,2...n-1,其中n表示棧的最大高度。咱們須要制定一種映射規則f,方便咱們經過index計算出f(index)。而最簡單的規則就是f(index) = index。code
#include<iostream> template<typename Object> class Stack { public: Stack() { init(); } Stack(const Stack& rhs) { init(); index = rhs.index; for(int i = 0; i != index + 1; ++i) p[i] = rhs.p[i]; } Stack(Stack&& rhs):p(rhs.p),index(rhs.index) { rhs.p = nullptr; rhs.index = -1; } Stack& operator =(const Stack& rhs) { Stack copy(rhs); std::swap(p, copy.p); std::swap(index, copy.index); return *this; } Stack& operator =(Stack&& rhs) { std::swap(p, rhs.p); std::swap(index, rhs.index); return *this; } ~Stack() { if(p) delete[] p; } void push(const Object& object) { if(index == MAX_SIZE-1) std::cerr << "overflow" << std::endl; else p[++index] = object; } void push(Object&& object) { if(index == MAX_SIZE-1) std::cerr << "overflow" << std::endl; else p[++index] = std::move(object); } void pop() { if(empty()) std::cerr << "underflow" << std::endl; else --index; } Object& top() { return p[index]; } const Object& top() const { return p[index]; } bool empty() const { return index == -1; } private: static constexpr int MAX_SIZE = 4; Object* p; int index; void init() { p = new Object[MAX_SIZE]; index = -1; } };
隊列的數組實現隊列
須要保存哪些變量? 隊列頭下標head、隊列長度size(用來計算隊列尾下標和判斷上溢出、下溢出),數組p和總長度MAX_SIZE。get
#include <iostream> template<typename Object> class Queue { public: Queue(){init();} Queue(const Queue& rhs) { init(); head = rhs.head; size = rhs.size; for(int i = head, idx; i != head + size; ++i) { idx = index(i); p[idx] = rhs.p[idx]; } } Queue(Queue&& rhs):head(rhs.head), size(rhs.size),p(rhs.p) { rhs.head = -1; rhs.size = 0; rhs.p = nullptr; } Queue& operator =(const Queue& rhs) { Queue copy(rhs); std::swap(head, copy.head); std::swap(size, copy.size); std::swap(p, copy.p); return *this; } Queue& operator =(Queue&& rhs) { std::swap(head, rhs.head); std::swap(size, rhs.size); std::swap(p, rhs.p); return *this; } ~Queue() { if(p) delete[] p; } void enqueue(const Object& object) { if(full()) { std::cout << "overflow" << std::endl; return; } p[index(head + size++)] = object; } void enqueue(Object&& object) { if(full()) { std::cout << "overflow" << std::endl; return; } p[index(head + size++)] = std::move(object); } Object tail() { if(empty()) { std::cout << "underflow" << std::endl; return Object(); } return p[index(head + size - 1)]; } Object dequeue() { if(empty()) { std::cout << "underflow" << std::endl; return Object{}; } Object& object = p[index(head)]; head = index(head + 1); --size; return object; } bool empty() const{return size == 0;} bool full() const {return size == MAX_SIZE;} int getSize() const {return size;} private: static constexpr int MAX_SIZE = 4; Object* p; int head; int size; void init() { p = new Object[MAX_SIZE]; head = size = 0; } inline int index(int i) { if(i >= MAX_SIZE) i -= MAX_SIZE; return i; } }; void testQueue() { using namespace std; struct Student { char name[10]; int age; }; Queue<Student> q; q.enqueue(Student{"Tom", 12}); q.enqueue(Student{"Micheal", 13}); q.enqueue(Student{"Anna", 14}); q.enqueue(Student{"Lily", 10}); q.enqueue(Student{"James", 19}); q.enqueue(q.dequeue()); q.enqueue(q.dequeue()); q.enqueue(q.dequeue()); q.enqueue(q.dequeue()); while(!q.empty()) { Student stu = q.dequeue(); cout << "name:" << stu.name << " age:" << stu.age << endl; } /*output overflow name:Tom age:12 name:Micheal age:13 name:Anna age:14 name:Lily age:10 */ }