- The underlying containers of Stack and Queue use deque.
- The simulation implementation of Stack (LIFO): insert, delete, take the top element of Stack, the size of Stack, and judge empty.
(insert, delete, and fetch top elements are all implemented in the tail.).
template <classT ,class Con = deque<T>>//Con -- abbreviation of container, container type. Here, deque is used as the adapter. class Stack{ public: Stack() {} void Push(const T&x){ _c.push_back(x); } void Pop(){ _c.pop_back(); } T& Top(){ return _c.back();//Take the element at the end (top of stack) } size_t Size(){ return _c.size(); } bool Empty(){ return _c.empty(); } private: Con _c; }; int main (){ Stack<int> st; st.Push(1); st.Push(2); st.Push(3); st.Push(4); cout << st.top() << endl; st.Pop(); cout << "Size:" << st.Size() << endl; cout << "Empty:" << st.Empty() << endl; return 0; }
The results are as follows:
- Simulation Implementation of Queue (first in first out): insert, delete, take the end element of Queue, take the top element of Queue, the size of Queue, and judge empty.
Note: the Print function cannot be defined inside the class to Print data:
void Print(){
while(!Empty()){
cout << _c.front() << endl;
_c.pop_front();
}
After this printing, all elements are deleted.
Therefore, data printing can only be implemented outside the class.
template <class T ,class Con = deque<int>> class Queue{ public: Queue() {} void Push(const T& x){ _c.push_back(x); } void Pop(){ _c.pop_front(); } T& Back(){ return _c.back();//Take tail element } T& Front(){ return _c.front();//Take the head element } size_t Size(){ return _c.size(); } boll Empty(){ return _c.empty(); } private: Con _c; }; int main (){ Queue<int> q; q.Push(1); q.Push(2); q.Push(3); q.Push(4); cout << "Team leader element:" << q.Front() << endl; cout << "Team ending element:" << q.Back() << endl; cout << "Size of the queue:" << q.Size() << endl; cout << "Whether the queue is empty:" << q.Empty() << endl; }
The results are as follows:
- The simulation implementation of priority queue: insert, delete, take the top element of the queue, the size of priority queue, and judge empty.
- At the bottom of the priority queue is the vector adapter, which by default is a large number of nodes (to be adjusted up when inserting, and to be adjusted down when deleting). When adjusting, the parameters give the subscript of the array.
Note: when adjusting the algorithm downward, the subscripts of child and child+1 should be controlled within the correct range.
template <class T, class Con = vector<T&>> class Priority_queue{ public: void Push(const T& x){ _c.push_back(x); Adjustup(_c.size()-1); } void Adjustup(int child){ int parent = (child-1)/2; while (child >0){ if (_c[child] > _c[parent]){ swap(_c[child],_c[parent]); child = parent; parent = (child-1)/2; } else{ break;//If not, exit the while loop. } } } void Pop(){ swap(_c[0],_c[_c.size()-1]); _c.pop_back();//Using tail deletion Adjustdown(0); } void Adjustdown(int root){ int parent = root; int child = parent*2+1; while(child < _c.size()){ if **(child+1 < _c.size() && _c[child]< _c[child+1])**{ swap(_c[child],_c[child+1]); } if (_c[parent] < _c[child]){ swap(_c[parent],_c[child]); parent = child; child = parent*2+1; } else{ break; } } T& top(){ return **_c[0];** } size_t Size(){ return _c.size(); } bool Empty(){ return _c.empty(); } private: Con _c; }; int main (){ Priority_queue<int> pq; pq.Push(1); pq.Push(2); pq.Push(3); pq.Push(4); cout << pq.top() << endl; while (pq.Size()){ cout << pq.Top() << " "; pq.Pop(); } cout << endl; cout << "Size:" << pq.Size() << endl; cout << "Empty:" << pq.Empty() << endl;
The results are as follows: