Suppose you have a queue that has 3 operations:
1.EnQueue (v): Add V to queue 2.DeQueue: Remove and return elements from queue first element 3.MaxElement: Returns the largest element in a queue design a data structure and algorithm to minimize the time complexity of maxelement operations Before studying this problem, we first study two sub-problems: 1, design a stack containing min operations 2, a stack to implement the queue one, design a stack containing min operations to add a member variable minvalue to the stack, when the elements into the stack, when the stack element compared to MinValue, if less than MI Nvalue, using the value of the stack element, update the MinValue, but the inefficiency is that if the stack element equals MinValue, you need to find the entire stack again to find the MinValue. The solution to this problem is to use a secondary stack, when an element is in the stack, the same position in the secondary stack to record the position of the smallest element in the stack before it is put into the stack. When out of the stack, if the stack element equals MinValue, find the element of the auxiliary stack counterpart, and remove the minimum value directly by position.
The leftmost number represents the position of the element in the stack. When 3 is in the stack, it is the smallest element, so in the secondary stack with its position in the same place, save it before the maximum position (-1 or 0 can be), 4 into the stack, considering 3 and help[0] equal, so 4 corresponding auxiliary stack element is 0, 2 into the stack, considering that 4 is greater than stack[help[1] ], so that the 2 corresponding auxiliary stack element is still 0, 1 is in the stack, because 2 is smaller than stack[help[2]], so 1 corresponds to the secondary stack element is the position of 2, that is, 2.
Source:
Template<typename t> class Minstack {private:t *stack; T *min; size_t top; T MinValue; size_t Maxelement;public:minstack (); ~minstack (); void push (T t); void Pop (); T GetTop (); T getmin ();}; Template<typename t> Minstack<t>::minstack () {maxelement = 20; stack = new T[maxelement]; min = new T[maxelement]; top =-1;} Template<typename t> Minstack<t>::~minstack () {delete[] stack; delete[] min;} Template<typename t> void Minstack<t>::p ush (T t) {if (top = = maxelement) {cout<< "It ' s full" ; Return } if (top = =-1) {stack[++top] = t; Min[top] = 0; MinValue = t; } else {stack[++top] = t; Min[top] = stack[top-1]>stack[min[top-1]]?min[top-1]:top-1; MinValue = t>stack[min[top]]?stack[min[top]]:t; }} template<typename t> void Minstack<t>::p op () {if (top==-1) {cout<< "It ' s Empty"; Return } if (top = = 0) {--top; } else {--top; MinValue = stack[min[top+1]]; }} template<typename t> T minstack<t>::gettop () {if (top==-1) {cout<< "It ' s empty stack"; Exit (0); } return stack[top];} Template<typename t> T minstack<t>::getmin () {if (top==-1) {cout<< "It ' s empty stack"; Exit (0); } return MinValue;}
Second, the implementation of the queue with two stacks the key is to set up a stack for the team, and the other stack to be used out. The first out of the stack team is empty, when there is a team action, will be queued stack all out of the stack, into the stack to out of the team stack, so that the order is just the reverse, the next time out of the team directly from the team to take the elements, the queue continues into the queue stack. Summing up is the: team has been in the queue stack into the stack. when the team out of the queue, if the stack is empty, put the stack all out of the stack into the stack, and then take the top element of the stack, move the top pointer, if the stack is not empty, directly take the element, move the pointer. Source:
Template<typename t> class Stack {public:t *s; size_t top; size_t Max; Stack (); ~stack (); void push (T t); void Pop (); T GetTop ();}; Template<typename t> class Queue {private:stack<t> En; Stack<t> de;public:void EnQueue (T t); T DeQueue ();}; Template<typename t> Stack<t>::stack () {Max = 20; s = new T[max]; top =-1;} Template<typename t> Stack<t>::~stack () {delete[] s;} template<typename t> void Stack<T>::p Ush (T T) {if (Top==max) {cout<< "It ' s full stack"; Return } S[++top] = t;} Template<typename t> void Stack<t>::p op () {if (top = =-1) {cout<< "It ' s empty Stack"; Return }--top;} Template<typename t> T stack<t>::gettop () {return s[top];} template<typename t> void Queue<T>:: EnQueue (T t) {En.push (t);} template<typename t> T queue<t>::D equeue () {if (de.top==-1) {while (en.top+1>0) {De.push (En.gettop ()); En.pop (); }} if (De.top==-1) {cout<< "It ' s empty queue"; } T temp = De.gettop (); De.pop (); return temp;}
After resolving these two sub-problems, the maximum operation in the queue is resolved. Modify the queue definition, replace the stack with Minstack, and add a minvalue () function.
Template<typename T> class Queue {private: minstack<t> En; minstack<t> de;public: void EnQueue (T t); T DeQueue (); T MinValue ();}; Template<typename t> T Queue<t>::minvalue () { if (de.top==-1&&en.top==-1) { cout << "It ' s a empty queue"; Exit (0); } else if (de.top = =-1) { return en.minvalue; } else if (en.top = =-1) { return de.minvalue; } else { return en.minvalue<de.minvalue? En.MinValue:De.MinValue;} }
If you do not use a template, directly with int or float, you can initialize the MinValue value in the Minstack to Int_max, and if the team is empty minvalue to int_min, so can omit en empty, de empty or en not empty the discussion of the de empty.
Issue: Design a queue to get the maximum queue value in O (1) Time # include <stdio.h> #include <queue> #include <stack>//o (1) The speed of the stack is taken out template<typename t>class maxstack {public://into stack void Push (const t& value) {Data_.push (value); if ( Max_element_.empty ()) {Max_element_.push (value);} else if (value >= max_element_.top ()) {Max_element_.push (value);} }//return stack top element T top () {return data_.top (); }//out stack void Pop () {if (data_.top () = = Max_element_.top ()) {Max_element_.pop (); } data_.pop (); }//determines whether the empty bool empty () {return data_.empty (); }//Remove maximum value T max () {if (!max_element_.empty ()) {return max_element_.top (); }}private:std::stack<t> Data_; Std::stack<t> max_element_;};/ /O (1) speed out of queue Max Template<typename T>class maxqueue {public://queued operation!!!!! void Push (const t& value) {Push_stack_. Push (value); }//takes the first element T Front () {if (Pop_stack_.empty ()) {while (!push_stack_. Empty ()) {Pop_stack_. Push (Push_stack_. Top ());p Ush_stack_. Pop ();}} Return Pop_stack_. Top ();} Team Operation!!!! void Pop () {if (pop_stack_). Empty ()) {while (!push_stack_. Empty ()) {Pop_stack_. Push (Push_stack_. Top ());p Ush_stack_. Pop ();}} Pop_stack_. Pop ();} EMPTY OPERATION!!!!! BOOL IsEmpty () {return push_stack_. Empty () && pop_stack_. Empty ();} Remove the maximum value of T Max () {if (!push_stack_). Empty () &&!pop_stack_. Empty ()) {return push_stack_. Max () > Pop_stack_. Max ()? Push_stack_. Max (): Pop_stack_. Max ();} else if (push_stack_. Empty () &&!pop_stack_. Empty ()) {return pop_stack_. Max ();} else if (!push_stack_. Empty () && pop_stack_. Empty ()) {return push_stack_. Max ();} else{throw Runtime_error;}} Private:maxstack<t> Push_stack_; Maxstack<t> pop_stack_;};/ /test Case int main (int argc, char** argv) {maxqueue<int> max_queue;max_queue. Push (1); Max_queue. Push (2); Max_queue. Push (6); Max_queue. Push (4); Max_queue. Push (5); Max_queue. Push (2);p rintf ("Max%d\n", Max_queue. Max ()); Max_queue. Pop ();p rintf ("Max%d\n", Max_queue. Max ()); Max_queue. Pop ();p rintf ("Max%d\n ", Max_queue. Max ()); Max_queue. Pop ();p rintf ("Max%d\n", Max_queue. Max ()); Max_queue. Pop ();p rintf ("Max%d\n", Max_queue. Max ()); Max_queue. Pop ();p rintf ("Max%d\n", Max_queue. Max ());}
Take maximum action in queue