3. 陣列實現的雙端佇列
阿新 • • 發佈:2018-12-24
- 《演算法導論》10.1-5 棧插入和刪除元素只能在同一端進行,佇列的插入操作和刪除操作分別在兩端進行,與它們不同的,有一種雙端佇列(deque),其插入和刪除操作都可以在兩端進行。寫出4個時間均為O(1)的過程,分別實現在雙端佇列的兩端插入和刪除元素的操作,該佇列是用一個數組實現的。
#include <iostream> template<typename Object> class Deque { public: Deque() { init(); } Deque(const Deque& 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]; } } Deque(Deque&& rhs):p(rhs.p),head(rhs.head),size(rhs.size) { rhs.p = nullptr; rhs.head = rhs.size = 0; } Deque& operator =(const Deque& rhs) { Deque copy(rhs); std::swap(copy.p, this->p); std::swap(copy.head, this->head); std::swap(copy.size, this->size); return *this; } Deque& operator =(const Deque&& rhs) { std::swap(rhs.p, this->p); std::swap(rhs.head, this->head); std::swap(rhs.size, this->size); return *this; } void push_front(const Object& object) { if(full()) { std::cout << "overflow" << std::endl; } else { p[index(--head)] = object; ++size; } } void push_front(Object&& object) { if(full()) { std::cout << "overflow" << std::endl; } else { p[index(--head)] = std::move(object); ++size; } } void push_back(const Object& object) { if(full()) std::cout << "overflow" << std::endl; else p[index(head + size++)] = object; } void push_back(Object&& object) { if(full()) std::cout << "overflow" << std::endl; else p[index(head + size++)] = std::move(object); } Object pop_front() { if(empty()) { std::cout << "underflow" << std::endl; return Object(); } else { Object& object = p[head]; head = index(++head); --size; return object; } } Object pop_back() { if(empty()) { std::cout << "underflow" << std::endl; return Object(); } else { --size; return p[index(head + size)]; } } bool empty() const {return 0 == size;} bool full() const {return MAX_SIZE == size;} private: static constexpr int MAX_SIZE = 4; Object* p; int head; int size; inline void init() { p = new Object[MAX_SIZE]; head = size = 0; } inline int index(int i) const { if(i >= MAX_SIZE) i -= MAX_SIZE; else if(i < 0) i += MAX_SIZE; return i; } }; void testDeque() { using namespace std; struct Student { char name[10]; int age; }; Deque<Student> dq; dq.push_back(Student{"Tom", 12}); dq.push_back(Student{"Micheal", 13}); dq.push_back(Student{"Anna", 14}); dq.push_back(Student{"Lily", 10}); dq.push_back(Student{"James", 19}); decltype(dq) dq_copy(dq), dq_reverse; while(!dq_copy.empty()) { auto stu = dq_copy.pop_front(); dq_reverse.push_front(stu); } dq_copy.pop_front(); while(!dq_reverse.empty()) { auto stu = dq_reverse.pop_back(); cout << "name: " << stu.name << " age: " << stu.age << endl; } decltype(dq) dq_move(std::move(dq)); } /*output: overflow underflow name: Tom age: 12 name: Micheal age: 13 name: Anna age: 14 name: Lily age: 10 */