使用递归对队列进行排序

时间:2012-01-31 10:16:12

标签: algorithm sorting queue

问题是:

您需要在添加到队列的新成员方法void sort()中对队列进行排序。

规则是:

  • 您不能使用任何循环。只允许递归。
  • 您可以根据需要创建任意数量的私有方法。
  • 您可以创建并使用相同类型的两个辅助队列(称之为Queue - 具有默认构造函数)。
  • 您对队列的内部结构一无所知。
  • 给您的唯一方法是:bool empty(), Data peek(), Data dequeue(), void enqueue(Data d)
  • 如果列表为空,则
  • dequeue()返回null,enqueue()忽略空输入。
  • 排序顺序需要升序(队列前面应该具有最小值)。
  • 可比较值在Data结构内的整数中,称为x

我知道它可以解决。我还没有找到答案。任何想法都将不胜感激。

5 个答案:

答案 0 :(得分:3)

开始排序N = 2个元素的队列。

现在 - 在解决这个问题之后 - 如果对N个元素进行排序,则改进对N + 1个元素进行排序的解决方案。


更新

现在,在您完成作业后,我可以在scala中展示另一种解决方案:

   private def insert (a: Int): Unit = {
     if (isEmpty || a <= peek) enqueue (a)
     else {
       val h = dequeue 
       insert (a)
       enqueue (h)
     }
   }

   def sort (): Unit = 
    if (! isEmpty) {
      val head = dequeue
      sort 
      insert (head)
    }

它没有明确的第二个队列。 insert是一个sortedInsert。

val q = new Queue (List (4))
q.enqueue (7)
q.enqueue (9)
q.enqueue (8)
q.enqueue (2)
q.enqueue (3)

val x = q.debug 
x: List[A] = List(3, 2, 8, 9, 7, 4)

q.sort 
val x = q.debug 
x: List[A] = List(2, 3, 4, 7, 8, 9)

我使用List来实现Queue,但仅将其用于创建新队列和出于调试原因。避免它不会是一个大问题,但它更快,我想从排序开始。 :)

答案 1 :(得分:2)

看看合并排序。它用于对磁带上的数据进行排序。我相信你可以将它用于排队。

答案 2 :(得分:2)

首先,谢谢你的回答。他们指出了正确的解决方案。我投票赞成他们,但是由于我设法解决了这个问题,我会接受我自己的答案(至少在有更好的答案之前)。

首先,家庭作业是关于“出租车”(你知道家庭作业是......)和一个TaxiQueue,用Java。

解决方案是:

public void sort() {
    sort(this);
}

private void sort(TaxiQueue toSort) {
    // Prepare split parts for later merging   
    TaxiQueue m1 = new TaxiQueue(), m2 = new TaxiQueue();

    // Return if there's only 1 element in the queue
    // since it's essentially "sorted".
    if(singleItem(toSort))
        return;

    // Split toSort into 2 parts
    split(toSort, m1, m2);
    // Sort each part recursively (by splitting and merging)
    sort(m1);
    sort(m2);
    // Merge each part into 1 sorted queue
    merge(toSort,  m1, m2);
}

private boolean singleItem(TaxiQueue tq) {
    Taxi temp = tq.dequeue();
    boolean retVal = tq.empty();
    tq.enqueue(temp);
    return retVal;
}

private void merge(TaxiQueue toSort, TaxiQueue m1, TaxiQueue m2) {
    // Notice that m1 and m2 are already sorted, and now we need
    // to merge them.
    // In the case that one of them is empty and the other one isn't,
    // simply append all remaining "higher" values into toSort.
    if(m1.empty()) {
        appendQueue(m2, toSort);
        return;
    }
    else if (m2.empty()) {
        appendQueue(m1, toSort);
        return;
    }
    // The critical comparison part...
    if(m1.peek().getId() < m2.peek().getId())
        toSort.enqueue(m1.dequeue());
    else
        toSort.enqueue(m2.dequeue());
    // Continue merging elements into toSort.
    merge(toSort, m1, m2);
}

// Split toSort into m1 and m2 as equally as possible
private void split(TaxiQueue toSort, TaxiQueue m1, TaxiQueue m2) {
    if(toSort.empty())
        return;
    m1.enqueue(toSort.dequeue());
    split(toSort,  m2, m1);
}

// Enqueue everything in src to dest.
private void appendQueue(TaxiQueue src, TaxiQueue dest) {
    if (src.empty())
        return;
    dest.enqueue(src.dequeue());
    appendQueue(src, dest);
}

我希望其他学生有一天能发现它有用!

答案 3 :(得分:0)

@Yam Marcovic:你的答案很好。虽然您最终创建的队列数与原始队列中的元素一样多。也许这是你不想做的事情。相反,你可以尝试一种更简单的方法,你只需要创建2个新队列(称为originalQ,Q1,Q2)。

我描述了递归步骤。

  • 假设Q1已经排序了n1个元素。
  • 让来自originalQ的新元素成为s。如果通过一次排队操作无法在Q中正确定位s,则保持Q1中的元素弹出(将它们与s进行比较)并将它们正确放入Q2中。
  • 现在您的Q2按n1 + 1个元素排序,Q1为空。 originalQ有一个元素少。请重复上述步骤。

答案 4 :(得分:0)

以下方法旨在仅使用一个额外队列来解决此问题。

该算法使用Recursion对队列进行排序。

假设我们有一个函数copy_from,它可以从一个队列复制到另一个队列,如下所示: -

  void copy_from (ArrayQueue&Q_from,ArrayQueue& Q_to){

       while(!Q_from.empty()){

       int t= Q_from.front();
       Q_to.enqueue(t);
       Q_from.dequeue();
     }
  }

主要排序功能如下所示: -

void sort(ArrayQueue &Q, int element, ArrayQueue& Q2){

if(Q.size()==1){

    if(Q.front()>element){

         int front = Q.front();
         Q.dequeue();
         Q.enqueue(element);
         Q.enqueue(front);      
    }
    else{
        Q.enqueue(element);
    }

}
else{

 int front = Q.front();
 Q.dequeue();
 sort_v2(Q,front,Q2);

 int sorted_front = Q.front();
 if(element<sorted_front){

    Q2.enqueue(element);
    copy_from(Q,Q2);
    copy_from(Q2,Q);     

 }
 else{

      Q2.enqueue(sorted_front);
      Q.dequeue();
      //push into Q2 those elements which are smaller than element in Q.
      while(!Q.empty()&&Q.front()<element){
         Q2.enqueue(Q.front());
         Q.dequeue();
      }

      Q2.enqueue(element);
      copy_from(Q,Q2);
      copy_from(Q2,Q);

 }

}
}

当我们最初调用sort函数时,我们可以按如下方式调用它: -

 Queue Q, Q2; //Assume Q is the queue we want to sort and Q2 is an empty queue.
int front = Q.front();
Q.dequeue();
sort(Q,front,Q2);