3-09. 队列中的元素排序(20)
时间限制 100 ms
内存限制 32000 kB
代码长度限制 8000 B
判题程序 Standard
给定一个队列,请用一系列合法的队列操作函数,包括:
(1) int IsEmptyQ(Queue Q)
(2) void AddQ(Queue Q, ElementType item)
(3) ElementType DeleteQ(Queue Q)
将队列中的元素从小到大排序。
注意:不能直接通过数组下标直接访问队列(数组)中的元素。可以使用一个辅助队列。排序后的结果应存放在原队列中。
输入格式说明:
输入首先给出1个正整数N(<=105),表示队列中元素的个数。随后按入队的顺序给出N个整数(这里假设item为整型数字)。
输出格式说明:
在一行中输出排序后出队的序列。数字间以空格分隔,但末尾不得有多余空格。
样例输入与输出:
序号 | 输入 | 输出 |
1 | | |
#include<stdio.h>
#include<queue>
using namespace std;
void print(queue<int> q)
{
bool first=true;
while(!q.empty())
{
if(first)
{
printf("%d",q.front());
first=false;
}
else
printf(" %d",q.front());
q.pop();
}
printf("\n");
}
int min(int x,int y)
{
if(x<=y)
return x;
else
return y;
}
//队列归并排序
void queueMergeSort(queue<int> &q, int size)
{
queue<int> qTemp; //用于辅助排序
int step=1; //步幅, 2的指数1,2,4,8
int remain; //标记还有多少元素未进行归并
int k1,k2,i; //k1:q复制到qTemp队列中的元素 k2:q中将要和qTemp合并的元素的个数
while(step<=size)
{
remain=size; //每次归并前,初始化大小为队列大小
while(remain>0) // 一次合并开始
{
k1=min(step,remain);
//将k1个元素放入qTemp中, k1是remain和step中的最小值
for(i=0;i<k1;i++){ qTemp.push(q.front()); q.pop(); }
remain=remain-k1; //更新剩余值
k2=min(remain,step); //q中要合并的元素个数
remain=remain-k2;
//对q和qTemp队列中的前k2,k1个元素,进行合并排序
while(k1>0 && k2>0) { //将较小的元素压入队列尾部
if(q.front()<=qTemp.front())
{ q.push(q.front()); q.pop(); k2--; }
else
{ q.push(qTemp.front()); qTemp.pop(); k1--;}
}
while(k2>0) {//q中还有剩余元素未合并(较大的),直接加入q队列尾部
q.push(q.front()); q.pop(); k2--;
}
while(k1>0) {//qTemp中还有剩余元素未合并(较大的),直接加入q队列尾部
q.push(qTemp.front()); qTemp.pop(); k1--;
}
}// 一次合并结束
//print(q);
step=step*2;
}
}
int main()
{
int N;
queue<int> q1;
queue<int> q2;
scanf("%d",&N);
int temp,i,j;
for(i=0;i<N;i++)
{
scanf("%d",&temp);
q1.push(temp);
}
queueMergeSort(q1,N);
print(q1);
}
参考: http://tech-wonderland.net/blog/pat-adt-3-09-sort-a-queue.html