您的位置:首页 > 其它

请设计一个队列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的值。效率相当的高。
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐