将两个队列合并为一个,交替从每个队列中获取元素

问题描述

我在 Xcode 中插入“merge_queues”函数时遇到了一些问题。
这是使用模板的队列

#include "Problem1.hpp"
using namespace std;

const int DefaultSize = 10;

template <class T>
class Queue
{

public:
    Queue(int queueCapacity = DefaultSize);
    
    void getSize();
    
    bool IsFull();
   
    T &Front() const;
    void push (const T& item);
    
  
    bool IsEmpty();

    T* pop(T&);
    // if IsEmpty(),then QueueEmpty(); else remove and return the topmost element of the Queue

    void QueueEmpty() {cout << "empty" << endl;};
    void QueueFull() {cout << "full" << endl;};
    void merge_queues(T &queue1,T &queue2);
  
    void Output();
private:
    int front;
    int rear;
    T *queue;
    int capacity;
};

这里是merge_queues函数

template <class T>
void  Queue<T>::merge_queues(T &queue1,T &queue2) {
    Queue<T> merged_queue;
    // inserting in final queue
    while(!IsEmpty() || !queue1.IsEmpty()) {
        // inserting element of q1 if q1 is non-empty
        if(!IsEmpty()) {
            merged_queue.push(Front());
            pop();
        }
        // inserting element of q2 if q2 is non-empty
        if(!queue1.IsEmpty()) {
            merged_queue.push(queue1.Front());
            queue1.pop();
        }
    }
    return merged_queue;
}

它在我的 Xcode 上没有任何错误, 但是我不知道如何在 main 函数中使用,有人可以帮我弄清楚吗?
这是我的主要功能

int main()
{
    int x;
    Queue<int> q1(5);
    Queue<int> q2(6);
    Queue<int> q3(11);
    
    cout<<"queue1:\n";
    q1.Output();
    q1.getSize();
    q1.push(1);
    q1.Output();
    q1.getSize();
    q1.push(2);
    q1.Output();
    q1.getSize();
    q1.push(3);
    q1.Output();
    q1.getSize();
    q1.push(4);
    q1.Output();
    q1.getSize();
    q1.push(5);
    q1.Output();
    q1.getSize();
    cout<<"queue2: \n";
    q2.Output();
    q2.getSize();
    q2.push(6);
    q2.Output();
    q2.getSize();
    q2.push(5);
    q2.Output();
    q2.getSize();
    q2.push(4);
    q2.Output();
    q2.getSize();
    q2.push(3);
    q2.Output();
    q2.getSize();
    q2.push(2);
    q2.Output();
    q2.getSize();
    q2.push(1);
    q2.Output();
    q2.getSize();
    q2.pop(x);
    q2.Output();
    q2.getSize();
    merge_queues(q1,q2);
    
}

merge_queues(q1,q2)发生错误
如何重写 merge_queues 以将两个队列合并为一个
谢谢。:)

我尝试了另一种方法函数 merge_queues 更改为

template <class T>
void  Queue<T>::merge_queues(T &queue1) {
    Queue<T> merged_queue;
    // inserting in final queue
    while(!IsEmpty() || !queue1.IsEmpty()) {
        // inserting element of q1 if q1 is non-empty
        if(!IsEmpty()) {
            merged_queue.push(Front());
            pop();
        }
        // inserting element of q2 if q2 is non-empty
        if(!queue1.IsEmpty()) {
            merged_queue.push(queue1.Front());
            queue1.pop();
        }
    }
    return merged_queue;
}

和主函数

 q1.merge_queues(q2);

错误

Non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'Queue<int>'

不知道是不是模板的问题

解决方法

这是一个使用 std::queue 的工作程序。您的自定义 Queue 类的逻辑将相同。请注意,我只检查一次队列是否为空。您检查作为循环条件,但由于您选择了 ||,因此您不得不再次检查。最好先处理简单的部分(当两者都不为空时),然后将其余部分作为单独的任务计算出来。

分离您的关注点使您的代码更易于编写和管理。

#include <iostream>
#include <queue>
#include <random>

std::queue<int> merge(std::queue<int>& q1,std::queue<int>& q2) {
  std::queue<int> merged;

  while (!q1.empty() && !q2.empty()) {
    merged.push(q1.front());
    q1.pop();
    merged.push(q2.front());
    q2.pop();
  }

  // By this point,one of the queues is empty,we merely have to add the
  // remaining elements of the other queue
  std::queue<int>& remain = q1.empty() ? q2 : q1;
  while (!remain.empty()) {
    merged.push(remain.front());
    remain.pop();
  }

  return merged;
}

int main() {
  // Set up
  std::mt19937 prng(std::random_device{}());
  std::uniform_int_distribution<int> sizes(10,30);

  std::queue<int> odds;
  std::queue<int> evens;

  int oddSize = sizes(prng);
  int evenSize = sizes(prng);

  // Fill odds
  for (int i = 1,idx = 0; idx < oddSize; i += 2,++idx) {
    odds.push(i);
  }

  // Fill evens
  for (int i = 2,idx = 0; idx < evenSize; i += 2,++idx) {
    evens.push(i);
  }

  std::cout << "Odd size: " << odds.size() << "\nFront: " << odds.front()
            << "\nBack: " << odds.back() << "\n\n";
  std::cout << "Even size: " << evens.size() << "\nFront: " << evens.front()
            << "\nBack: " << evens.back() << "\n\n";

  // Merge and print merged
  auto m = merge(odds,evens);
  while (!m.empty()) {
    std::cout << m.front() << ' ';
    m.pop();
  }
  std::cout << '\n';
}

输出:

Odd size: 20
Front: 1
Back: 39

Even size: 14
Front: 2
Back: 28

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 31 33 35 37 39

您的合并代码看起来不错,尽管有点不稳定。该问题可能与您的 Queue 类的实现有关。这就是测试驱动开发发挥作用的地方。

您认为错误出在一处,但很可能在另一处。在您编写完 Queue 类之后,您是否对其进行了任何测试?您有一些没有意义的函数,例如 QueueEmpty()QueueFull()。怎么可能满?调用一个只打印出来的函数有什么好处?

我不知道您要使用动态数组还是链表作为 Queue 的后备存储。我想通过全面检查,您将使用动态数组。

您需要区分 .front() & .back().pop()

您声称您的 Queue 是一个模板类,但您将 frontback 存储为 int,为什么?