【发布时间】:2010-10-23 12:54:27
【问题描述】:
有没有办法只使用两个临时队列(并且没有其他变量,例如计数器)来反转队列中的项目顺序?只有标准队列操作可用:ENQUEUE(e)、DEQUEUE()、EMPTY()?
欢迎使用任何语言或伪代码的解决方案。
【问题讨论】:
-
@nobody_,你不知道这是家庭作业(这就是为什么我相信闻起来像...标签是发明的)。而且,即使是,这是一个有效的问题。
有没有办法只使用两个临时队列(并且没有其他变量,例如计数器)来反转队列中的项目顺序?只有标准队列操作可用:ENQUEUE(e)、DEQUEUE()、EMPTY()?
欢迎使用任何语言或伪代码的解决方案。
【问题讨论】:
你可以:
【讨论】:
我意识到这个线程早已死去,但我相信我找到了一个很好的解决方案,可以满足所有要求。
您只需要一个临时队列。只要原始队列不为空,您所做的就是将队列中的最后一个节点移动到前面,方法是设置一个指向最后一个节点的指针,然后将节点出队并重新入队到原始队列中。 然后你从原始队列中出队并进入临时队列。 之后,您只需将 temp 复制回原始队列。
这是我的 C 语言解决方案,ADT 风格: (至少我不用担心为你做作业)
QUEUE *reverseQueue (QUEUE *queue) {
QUEUE *temp;
QUEUE_NODE *pLast;
void *dataPtr;
//Check for empty queue
if(emptyQueue(queue))
return NULL;
//Check for single node queue
if(queueCount(queue) == 1)
return queue;
temp = createQueue();
while(!emptyQueue(queue))
{
pLast = queue->rear;
//Move last node to front of queue
while(queue->front != pLast)
{
dequeue(queue, &dataPtr);
enqueue(queue, dataPtr);
}
//Place last node in temp queue
dequeue(queue, &dataPtr);
enqueue(temp, dataPtr);
}
//Copy temp queue back to original queue
while(!emptyQueue(temp))
{
dequeue(temp, &dataPtr);
enqueue(queue, dataPtr);
}
destroyQueue(temp);
return queue;
}
【讨论】:
// REVERSE OF QUEUE USING 1 QUEUE N OTHER DEQUEUE
void reverse() {
int q1[20],q2[20],f1,r1,f2,r2;
while(f1!=r1) {
q1[r2]=q1[f1];
r2=r2+1;
f1=f1+1;
}
//whole elements of temporary queue is transfered to dequeue.
while(r2!=f2) {
q1[r1]=q2[r2];
r2=r2-1;
r1=r1+1;
}
}
【讨论】:
因此,这样做的方法是将原始队列中的所有内容(最后一项除外)出列到临时队列中,将最后一项放入最终队列中。然后重复,每次将除最后一个之外的每个项目从一个临时队列复制到另一个,并将最后一个复制到最终队列。嗯....有更好的方法吗?
【讨论】:
while(!queue.EMTPY())
{
while(!finalQueue.EMPTY())
{
tempQueue.ENQUEUE(finalQueue.DEQUEUE());
}
finalQueue.ENQUEUE(queue.DEQUEUE());
while(!tempQueue.EMPTY())
{
finalQueue.ENQUEUE(tempQueue.DEQUEUE());
}
}
我认为这应该可行。如果您可以将临时队列和最终队列与原始队列中的每个出队交换,则有一种更有效的方法。
【讨论】:
答案是肯定的。我很想把它留在那里,因为这听起来像是一个家庭作业问题,但我认为这是一个有趣的问题。
如果只能使用这三个操作,则必须同时使用两个临时队列。
基本上,您必须从主队列中出列并将项目放入临时队列 A。将临时队列 B 中的所有项目(起初为空)出列到 A。然后做同样的事情,只是将顺序从 A 反转到 B。您总是排队进入空的临时队列,然后放入其他临时队列中的所有项目。当要反转的队列为空时,您可以从非空临时队列中出列并入队到主队列中,您应该被反转。
我会给出伪代码,但我又担心我正在为你做作业。
【讨论】:
这有点类似于Tower of Hanoi 谜题:)
这是 C# 中的一个解决方案:
static Queue<T> ReverseQueue<T>(Queue<T> initialQueue)
{
Queue<T> finalQueue = new Queue<T>();
Queue<T> intermediateQueue = new Queue<T>();
while (initialQueue.Count > 0)
{
// Move all items from the initial queue to the intermediate queue,
// except the last, which is placed on the final queue.
int c = initialQueue.Count - 1;
for (int i = 0; i < c; i++)
{
intermediateQueue.Enqueue(initialQueue.Dequeue());
}
finalQueue.Enqueue(initialQueue.Dequeue());
// Swap the 'initialQueue' and 'intermediateQueue' references.
Queue<T> tempQueue = initialQueue;
initialQueue = intermediateQueue;
intermediateQueue = tempQueue;
}
return finalQueue;
}
【讨论】:
要从队列中反转作为队列内容的字符串,我们需要另外两个队列 在第一个队列中,将除最后一个以外的所有元素出列,并将它们排入第二个队列。 现在将第三个队列中的最后一个元素排入队列,这是结果队列。执行从第二个到第一个队列的事务并将第三个堆栈中的最后一个元素排入队列。 重复此操作,直到两个堆栈都为空。
【讨论】: