【问题标题】:Subtle bugs in implementing circular queue实现循环队列的细微错误
【发布时间】:2023-03-03 03:24:01
【问题描述】:

我正在尝试实现一个简单的循环队列操作,如下所示

void push(int theElement)
{
  //Check if the push causes queue to overflow
    if  (((queueBack + 1 ) % arrayLength) == queueFront) {
       std::cout<<"Queue is full."<<std::endl;
       return ;
    } 
    queueBack = (queueBack + 1) % arrayLength;
    inputArray[queueBack] = theElement;
}

int pop()
{
   //Check if queue  is already empty
  if ( queueFront == queueBack ) {
    std::cout<<"Queue is empty."<<std::endl;
    return;
  }
  queueFront = (queueFront + 1 ) % arrayLength;
  return inputArray[queueFront];

}

考虑到最初 queueFront = 0 和 queueBack = 0, 上面的代码会导致一个完整的队列,即使实际上不是。我该如何纠正?在第一种情况下我的实现是否正确?

测试用例 最初arrayLength = 3,queueFront = 0,queueBack = 0;

  1. 在第一次调用 push(1) 结束时; queueFront = 0 , queueBack = 1 , 1 被添加到 inputArray[1] 而不是 0;

  2. 在第二次调用 push(2) 结束时,queueFront = 0, queueBack = 2, , 2 被添加到 inputArray[2],

  3. 现在,(queueBack + 1) % arrayLength == queueFront 为真,而还剩下一个空白空间,即 inputArray[0]。

谢谢

【问题讨论】:

  • 你能用一些输入值解释这段代码有什么问题吗?你的意思是当它没有满时它会给出完整的队列?
  • 当您使用 c++ 时,您应该将功能封装到一个类中,而不是使用全局变量。即使在 C 中为此使用全局变量也是一种糟糕的风格。
  • 同意@MichaelWalz,但让我们暂时忘记复杂性。我想先想出正确的逻辑。
  • 正如您在第 1 点下的问题中解释的那样,1 被添加到 inputArray[1] 而不是 inputArray[0],这很明显,之前 yun 增加了 queueBack。
  • 我刚刚注意到您的变量名称是非标准的。通常情况下,queueFront 在推送项目时被推进,而 queueBack 在项目被弹出时推进,即后面跟随前面。

标签: c queue


【解决方案1】:

这不是错误,它是循环队列的一个特性。如果您不留下一个空槽,则无法区分满箱和空箱。当然,pop 函数应该返回它从队列中读取的 int,不需要将值设置为 -1。

【讨论】:

  • 在这种情况下,将值设置为 -1 是一个错误,因为它是在 queueFront 递增之后完成的(因此它会踩到下一个元素)。
  • 不正确,因为 OP 预先增加了两个指针,所以没有错误。我同意后增量更直观,但如果 OP 用 return 语句替换最后一行(以返回值),那么您可以看到预增量实际上更有效。
  • 啊,我明白了。我的错。
  • @user3386109,我修改了pop()函数,现在正确了吗?
猜你喜欢
  • 2014-01-04
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2017-04-08
  • 2020-02-10
  • 1970-01-01
  • 2012-01-30
相关资源
最近更新 更多