请设计一个队列FIFO,要求包含min max mid函数

来源:互联网 发布:手机桌面美化软件 编辑:程序博客网 时间:2024/06/06 00:32
转载请注明出处:http://blog.csdn.net/shandianling/article/details/7997163
解释:min()要求返回队列中的最小值
  max()要求返回队列中的最大值
   mid()要求返回队列中倒数第(size()+1)/2小的值。说白了就是把队列变成有序后最中间那个值。
思想:把两个双向链表,一个保存队列顺序,一个是有序的。然后就整成一个链表。
   要保证有序,在链表中本人觉得插入排序不错。这里在push_back()的时候就插入到合适的位置,成为一个新的有序链表。
    竟然有序了,求最小值、最大值,就容易了,就一前一后。
    求mid的话,可以选择从有序表的前遍历一下,(size()+1)/2的位置就是所求。
   但我觉得还是慢了。如果已知mid的位置,push_back(),pop()很可能改变mid的位置,但只要相应的前进、后退一位或不动,就OK了。
   然后直接返回mid的值。效率相当的高。
#include <iostream>#include <assert.h>using namespace std;struct Node{int key;//正常FIFOstruct Node *pLeft;struct Node *pRight;//有序struct Node *pre;struct Node *pNext;};class dequeWithOrder{typedef int key_type;typedef struct Node _Node;public:dequeWithOrder(){head=minNode=midNode=0;nelems=0;}~dequeWithOrder(){clear();}void clear(){if(head==NULL) return;Node* final=head->pre;Node* q=head;while(head !=final){q=head;head=head->pRight;delete q;}delete head;head=midNode=minNode=NULL;nelems=0;}void push_back(const key_type &key){Node* newNode=new Node;newNode->key=key;if(NULL==head){head=newNode;newNode->pLeft=newNode->pRight=head;//有序minNode=midNode=head;newNode->pre=newNode->pNext=head;}else{//正常FIFONode* back=head->pLeft;back->pRight=newNode;newNode->pRight=head;newNode->pLeft=back;head->pLeft=newNode;//有序插入//1) key<最小值 插在最前Node* maxNode=minNode->pre;if(key < minNode->key){newNode->pre=maxNode;newNode->pNext=minNode;maxNode->pNext=newNode;minNode->pre=newNode;//调整minNode midminNode=newNode;//如果是之前是奇数个元素,则位置本不动,但新元素放在最前,所以要后移一位if((nelems & 1) !=0 )midNode=midNode->pre;}//2)key >=最大值else if(key >= maxNode->key){newNode->pre=maxNode;newNode->pNext=minNode;maxNode->pNext=newNode;minNode->pre=newNode;//如果是之前是偶数个元素,则mid要后移一位if((nelems & 1)==0)midNode=midNode->pNext;}// 3)在之间else{Node* q=minNode->pNext;while(q!=maxNode){if(key < q->key) break;q=q->pNext;}newNode->pre=q->pre;newNode->pNext=q;newNode->pre->pNext=newNode;q->pre=newNode;//update midNode while minNode isnt changedif((nelems & 1)!=0 && key<midNode->key)midNode=midNode->pre;else if((nelems & 1)==0 && key>=midNode->key)midNode=midNode->pNext;}}cout <<" cur Mid:" << midNode->key <<endl;++nelems;}void pop(){if(NULL==head) return;if (head->pRight == head){delete head;head=midNode=minNode=NULL;nelems=0;return;}//正常popNode* delNode=head->pLeft;head->pLeft=delNode->pLeft;delNode->pLeft->pRight=head;//删除有序中的元素delNode->pre->pNext=delNode->pNext;delNode->pNext->pre=delNode->pre;//删除是midNode这个点if(delNode==midNode){if((nelems&1)==1) midNode=midNode->pre;else midNode=midNode->pNext;}else{if(delNode->key >= midNode->key){if((nelems&1)==1)midNode=midNode->pre;}else{if((nelems& 1)==0)midNode=midNode->pNext;}}if(delNode==minNode) minNode=minNode->pNext;delete delNode;--nelems;}key_type top() const{assert(head);return head->pLeft->key;}//返回倒数第(size()+1)/2个最小的值//如果升序排序,就是最中间那个值,注意奇偶数个元素时。key_type mid() const{assert(head);return midNode->key;}unsigned int size() const{return nelems;}void pr_deque(){if(head==NULL) return;Node* back=head->pLeft;Node* q=head;while(q!=back){cout << q->key << " ";q=q->pRight;}cout << q->key << " ";}void pr_orderList(){if (head == NULL) return;Node* maxNode = minNode->pre;Node* q = minNode;while (q != maxNode){cout << q->key << " ";q = q->pNext;}cout << q->key << " ";}private:_Node* head;_Node* minNode;_Node* midNode;unsigned int nelems;//元素的个数};int main() {dequeWithOrder sl;sl.push_back(12);sl.push_back(14);sl.push_back(100);sl.push_back(13);sl.push_back(13);sl.push_back(122);sl.push_back(45);sl.push_back(46);sl.push_back(888);sl.push_back(5);sl.push_back(18);cout << "队列元素顺序为:" << endl;sl.pr_deque();cout << endl;cout << "排序后:" << endl;sl.pr_orderList();cout << endl;cout << "mid:" << sl.mid() << endl;cout <<"\npop "<<sl.top()<<endl;sl.pop();sl.pr_orderList();cout << endl;cout << "mid:" << sl.mid() << endl;cout <<"\npop "<<sl.top()<<endl;sl.pop();sl.pr_orderList();cout << endl;cout << "mid:" << sl.mid() << endl;cout <<"\npop "<<sl.top()<<endl;sl.pop();sl.pr_orderList();cout << endl;cout << "size: " << sl.size() << endl;cout << "mid:" << sl.mid() << endl;sl.clear();return 0;}

原创粉丝点击