栈和队列的比较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 */ }