c# - 优先级队列删除具有相同优先级的项目第一个进入
问题描述
我已经创建并工作了一个优先队列,它按顺序输入项目并按顺序删除它们。即使两个数字具有相同的优先级,它也会删除第一个输入的数字。
如果存在三个具有相同优先级的数字,则不会删除第一个。我将如何去做,或者它应该这样做?
出队功能:
public void deQueue(Animal item)
{
item = items.elements[0];
items.elements[0] = items.elements[numItems - 1];
numItems--;
items.ReheapDown(0, numItems - 1);
}
ReheapDown 函数:
public void ReheapDown(int root, int bottom)
{
int maxchild, rightchild, leftchild;
leftchild = root * 2 + 1;
rightchild = root * 2 + 2;
if (leftchild <= bottom)
{
if (leftchild == bottom)
maxchild = leftchild;
else
{
if (elements[leftchild].priority <= elements[rightchild].priority)
maxchild = rightchild;
else
maxchild = leftchild;
}
if (elements[root].priority < elements[maxchild].priority)
{
Swap(elements, root, maxchild);
ReheapDown(maxchild, bottom);
}
}
}
解决方案
在这一行
if (elements[leftchild].priority <= elements[rightchild].priority)
如果它们相等,则交换元素。因此,假设您[2, 2, 1, 3]
按顺序输入 numbers 。让我们称第二个2
为“ 2*
”,以区别于第一个。结果堆是:
1
/ \
2 2*
/
3
现在,您删除1
. 因此,您将其替换1
为3
:
3
/ \
2 2*
在您的ReheapDown
方法中,父母有两个孩子,您正在选择最小的孩子。当您比较两者时2
,您有以下代码:
if (elements[leftchild].priority <= elements[rightchild].priority)
maxchild = rightchild;
else
maxchild = leftchild;
因为2 == 2
, 它设置maxchild = rightchild
, 所以新的根变成-- 输入的2*
第二个2
。你的堆现在看起来像这样:
2*
/ \
2 3
接下来要删除的将是2*
.
那么,您可能会认为,如果您将其更改<=
为<
,它将解决您的问题。但它不会。
当您考虑堆可以变异的所有不同方式时,除非您提供其他信息,否则无法保证相同的项目将按照插入的顺序被删除。考虑一下如果您在订单中输入项目会发生什么[1, 3, 2, 2*]
。结果堆是:
1
/ \
2* 2
/
3
如果您删除1
,您最终会得到:
3
/ \
2* 2
在这种情况下,这<=
会帮助你。但在前一种情况下,它不会。
保证相等项目的删除顺序的唯一方法是在比较中添加第二个条件 - 基本上,您必须使这些相等的项目不相等。您需要在密钥中添加日期戳或序列号,以便识别广告订单。
推荐阅读
- vba - 尝试处理 mailitem 对象时需要错误 424 对象
- python - 导入 Tkinter 和行跨度/粘性问题
- r - R删除levelplot grobs之间的空白
- java - 我可以将 Maximo 集成框架从 7.5 版升级到 7.6 版吗?
- java - EntityManager 使用依赖注入导致的死锁
- javascript - 有没有办法保存 ajax 函数/调用以便可以重复使用?
- python-2.7 - 芹菜通过对等错误引发连接重置
- python-3.x - ValueError: 'conv1d_1/convolution/Conv2D 从 1 中减去 3 导致的负维度大小
- twilio - 如何在 Twilio Flask App 中获取来电者的电话号码?
- java - Java Play Framework 2.6 不返回“Access-Control-Allow-Origin”CORS 标头