请设计一个队列FIFO,要求包含min max mid函数
2012-09-19 17:47
357 查看
转载请注明出处:/article/8089302.html
解释:min()要求返回队列中的最小值
max()要求返回队列中的最大值
mid()要求返回队列中倒数第(size()+1)/2小的值。说白了就是把队列变成有序后最中间那个值。
思想:把两个双向链表,一个保存队列顺序,一个是有序的。然后就整成一个链表。
要保证有序,在链表中本人觉得插入排序不错。这里在push_back()的时候就插入到合适的位置,成为一个新的有序链表。
竟然有序了,求最小值、最大值,就容易了,就一前一后。
求mid的话,可以选择从有序表的前遍历一下,(size()+1)/2的位置就是所求。
但我觉得还是慢了。如果已知mid的位置,push_back(),pop()很可能改变mid的位置,但只要相应的前进、后退一位或不动,就OK了。
然后直接返回mid的值。效率相当的高。
解释: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; //正常FIFO struct 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 { //正常FIFO Node* 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 mid minNode=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 changed if((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; } //正常pop Node* 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; }
相关文章推荐
- 设计一个包含pop,push,min在内的栈,并且各个函数的时间复杂度均为o(1)
- 设计包含min函数的栈,要求函数min、push以及pop的时间复杂度都是O(1)
- 每天学习一算法系列(3)--设计包含min函数的栈,要求函数min、push以及pop的时间复杂度都是O(1))
- 每天学习一算法系列(3)(设计包含min函数的栈,要求函数min、push以及pop的时间复杂度都是O(1))
- 【编程题目】设计包含 min 函数的栈
- 第二题(设计包含min 函数的栈)
- 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)
- 2.设计包含min 函数的栈。
- 3、定义一个结构体变量(包含年月日),计算该日在本年中为第几天?要求写一个days函数。参数是此结构体类型的变量,返回值是整数。
- 设计包含 min 函数的栈
- 面试题三:设计包含 min 函数的栈。
- 定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素
- 面试题:定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素,要求函数min,push及pop的时间复杂度都是O(1)
- 字符串匹配之通配符问题------一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。
- 微软面试100题系列-设计包含 min 函数的栈
- 设计一个函数,对传入的字符串(假设字符串中只包含小写字母和空格)进行加密操作,加密的规则是a变d,b变e,c变f,……,x变a,y变b,z变c,空格不变,返回加密后的字符串
- 一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。并分析时间复杂度与空间复杂度。
- //创建一个数组, //实现函数init()初始化数组、 //实现empty()清空数组、 //实现reverse()函数完成数组元素的逆置。 //要求:自己设计函数的参数,返回值。
- 设计一个日期类Date,,要求: (1)包含年(year)、月(month)和日(day)私有数据成员。 (2)包含构造函数,重载关于一日期加上天数的加法运算符+、重载关于一日期减去天数的减加运算符-
- 创建一个数组, 实现函数init()初始化数组、 实现empty()清空数组、 实现reverse()函数完成数组元素的逆置。 要求:自己设计函数的参数,返回值。