首页 > 代码库 > 编程之美——队列中取最大值操作

编程之美——队列中取最大值操作

     为实现O(1)的时间复杂度完成取队列中最大元素,使用maxStackItemIndex记录队列(使用两个栈实现)中最大元素下标,使用数组link2NextMaxItem[]记录数组中次大值的下标,这也就是使用两个栈(先进后出)模拟队列二不是直接使用队列(先进先出)的原因:先进后出可以保证当执行pop操作(pop出最大值)时可以更新maxStackItemIndex=link2NextMaxItem[stackTop];而队列则不具有这种回溯特性;

代码:

  1 #include<iostream>  2 using namespace std;  3 const int INF=10000;  4 const int MAXN=100;  5   6 class maxStack  7 {  8 private:  9     int stackItem[MAXN]; 10     int stackTop; 11     int link2NextMaxItem[MAXN]; //记录栈中第二大数字的下标 12     int maxStackItemIndex;  //记录站中最大数字下标 13  14 public: 15     maxStack() 16     { 17         stackTop=-1; 18         maxStackItemIndex=-1; 19     } 20  21     void push(int x); 22     int pop(); 23     int max() 24     { 25         if(maxStackItemIndex>=0) 26             return stackItem[maxStackItemIndex]; 27         else 28             return -INF; 29     } 30     bool empty() 31     { 32         return stackTop==-1; 33     } 34 }; 35  36 void maxStack::push(int x) 37 { 38     ++stackTop; 39     if(stackTop>MAXN) 40         //throw new Exception("stack is full!"); 41         cout<<"stack is full!"<<endl; 42     else 43     { 44         stackItem[stackTop]=x; 45         if(x>max()) 46         { 47             //更新过程 48             link2NextMaxItem[stackTop]=maxStackItemIndex; 49             maxStackItemIndex=stackTop; 50         } 51         else 52             link2NextMaxItem[stackTop]=-1; 53     } 54 } 55  56 int maxStack::pop() 57 { 58     if(stackTop==-1) 59         //throw new Exception("stack is empty!"); 60         cout<<"stack is empty!"<<endl; 61  62     int value=http://www.mamicode.com/stackItem[stackTop]; 63     if(value=http://www.mamicode.com/=max()) 64     { 65         //回溯第二大数字下标 66         maxStackItemIndex=link2NextMaxItem[stackTop]; 67     } 68     --stackTop; 69     return value; 70 } 71  72 //使用两个栈模拟队列 73 class maxQueue 74 { 75 private: 76     maxStack A,B; 77 public: 78     void enQueue(int x) 79     { 80         B.push(x); 81     } 82     int deQueue() 83     { 84         if(A.empty()) 85             while(!B.empty()) 86                 A.push(B.pop()); 87         return A.pop(); 88     } 89     int maxValue() 90     { 91         return A.max()>B.max() ? A.max():B.max(); 92     } 93 }; 94  95 int main() 96 { 97     maxQueue queue; 98     for(int i=5;i>0;--i) 99         queue.enQueue(i);100     for(int i=0;i<5;++i)101     {102         cout<<queue.maxValue()<<ends;103         queue.deQueue();104     }105     return 0;106 }
View Code

   上面是以栈为基础构造队列实现O(1)的取队列中最小元素,当然也可以直接使用队列实现,这里使用效率较高的循环队列;

具体:若入对元素大于队尾元素,则将队尾元素弹出,入队,这样可以保证队尾元素始终为最大值,直接返回即可;

代码:

 1 #include<iostream> 2 using namespace std; 3  4 class maxQueue 5 { 6 private: 7     int *queueItem; 8     int front,rear; 9     int maxSize;10 public:11     maxQueue(int size=5)12     {13         queueItem=new int[size];14         maxSize=size;15         front=rear=1;16     }17     int rearValue()18     {19         return queueItem[rear];20     }21     void doubleSpace();22     void enQueue(int x);23     int deQueue();24     int maxValue()25     {26         return queueItem[front];27     }28     bool isEmpty()29     {30         return front==rear;31     }32     ~maxQueue()33     {34         delete [] queueItem;35     }36 };37 38 void maxQueue::enQueue(int x)39 {40     if((rear+1)%maxSize==front)41         doubleSpace();42 43     while(x>=rearValue())44     {45         --rear;46     }47     rear=(rear+1)%maxSize;48     queueItem[rear]=x;49 }50 51 int maxQueue::deQueue()52 {53     if(front==rear)54         cout<<"the queue is empty"<<endl;55 56     int value=http://www.mamicode.com/queueItem[front];57     front=(front+1)%maxSize;58     return value;59 }60 61 void maxQueue::doubleSpace()62 {63     int *tmp=queueItem;64 65     queueItem=new int[2*maxSize];66     for(int i=1;i<maxSize;++i)67         queueItem[i]=queueItem[front+i];68 69     maxSize*=2;70     delete tmp;71 }72 73 int main()74 {75     maxQueue queue;76     int arr[9]={4,3,2,1,5,4,3,2,1};77     for(int i=0;i<9;++i)78     {79         queue.enQueue(arr[i]);80         cout<<"max:"<<queue.maxValue()<<endl;81     }82     cout<<endl;83     while(!queue.isEmpty())84     {85 86         cout<<"max:"<<queue.maxValue()<<endl;87         queue.deQueue();88     }89 90     return 0;91 }
View Code

 

编程之美——队列中取最大值操作