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