当前位置: 首页 > 知识库问答 >
问题:

如何在基于堆的优先级队列中实现函数

诸葛阳成
2023-03-14

1)insert(name,priority):这个函数应该取一个string类型的名称和一个integer类型的优先级,并将它们插入到优先级队列中。remove():这个函数应该移除具有最高优先级值的对象,并从对象中返回名称字符串。

2)作为背景,我有三个类用于这个程序:第一,包含读取文件和使用函数的实现的“main”类。第二,“name”类,它创建包含名称字符串和优先级int的name对象、一个构造函数和一个用于比较两个对象的优先级值的compareTo方法。第三,“priorityqueue”类,包含insert和remove函数。下面是我为这两个函数制作的伪代码:

插入:

  • 检查数组是否已满(当num=255时),如果为true,则抛出
  • 使用名称字符串和优先级int从输入文件创建对象
  • 在Num处插入对象
  • 使用while循环在插入时交换两个对象
  • 更新num(num++)

删除:

    null
public class PriorityQueue 
{
int num; //amount of things in array 
int idx; //index of current name object
Name[] names = new Name[255];

public void insert(String name, int priority)
{
    while (num != 255)
    {
        Name addName = new Name(name, priority);
        names[num] = addName;
        num++;

        while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
        {
            Name temp = names[idx];
            names[idx] = names[(idx-1)/2];
            names[(idx-1)/2] = temp;

            idx = (idx-1)/2;
        }
    }
}

public Name remove()
{
    Name temp2 = names[0];
    //Save first element

    names[0] = names[idx];
    //Move last element to first

    num--;
    while(idx < Math.max(2*idx+1,2*idx+2))
    {
        if(names[idx].CompareTo(names[(idx-1)/2]))
                {
                    Name temp3 = names[idx];
                    names[idx] = names[(idx-1)/2];
                    names[(idx-1)/2] = temp3;
                }
    }
    return temp2;
}
public class Name implements Comparable
{
String name;
int priority;

public Name(String n, int i)
{
    name = n;
    priority = i;
}

public boolean CompareTo(Name obj)
{
    if(priority < obj.priority)
    {
        return false;
    }

    else if(priority > obj.priority)
    {
        return true;
    }

    return true;
}
}

共有1个答案

端木夕
2023-03-14

几个问题。首先,在insert方法中:

public void insert(String name, int priority)
{
    while (num != 255)
    {
        Name addName = new Name(name, priority);
        names[num] = addName;
        num++;

        while(idx != 0 || names[idx].CompareTo(names[(idx-1)/2]))
        {
            Name temp = names[idx];
            names[idx] = names[(idx-1)/2];
            names[(idx-1)/2] = temp;

            idx = (idx-1)/2;
        }
    }
}

while(num!=255)不应该在那里。您应该检查num==255,如果是,则抛出异常

然后,您需要初始化idx。即:

        Name addName = new Name(name, priority);
        names[num] = addName;
        idx = num;
        num++;
public Name remove()
{
    Name temp2 = names[0];
    //Save first element

    names[0] = names[idx];
    //Move last element to first

    num--;
    while(idx < Math.max(2*idx+1,2*idx+2))
    {
        if(names[idx].CompareTo(names[(idx-1)/2]) > 0)
                {
                    Name temp3 = names[idx];
                    names[idx] = names[(idx-1)/2];
                    names[(idx-1)/2] = temp3;
                }
    }
    return temp2;
}
names[0] = names[num-1]; // get last item in the heap
idx = 0;
while (idx < num)
while (idx < num)
{
    int largestChild = idx*2+1;
    if (largestChild >= num) break; // idx is at a leaf level
    if (largestChild+1 < num)
    {
        // compare the two children
        if (names[largestChild].compareTo(names[largestChild+1]) < 0)
        {
            largestChild = largestChild+1;
        }
    }
    if (names[idx] < names[largestChild])
    {
        // swap, moving the item down
        temp = names[idx];
        names[idx] = names[largestChild];
        names[largestChild] = temp;
        idx = largestChild;
    }
    else
    {
        // item is in the proper place
        break;
    }
}

我建议在这两个方法中使idx成为方法范围的变量。它不需要是全局的,使它成为方法的局部会迫使您在使用它之前对它进行初始化,而不是潜在地(如在现有代码中)使用一个过时的值。

我认为您需要更改name类的compareTo函数。可比的compareTo函数必须返回:

负整数、零或正整数,因为此对象小于、等于或大于指定对象。

public boolean CompareTo(Name obj)
{
    if(priority < obj.priority)
    {
        return -1;
    }

    if (priority > obj.priority)
    {
        return 1;
    }

    return 0;
}
 类似资料:
  • 我正在编写一个涉及堆实现的代码,在我的bubbleUp方法中,在我的while循环行中,我似乎遇到了一个取消引用的错误。这可能是一个相当基本的问题,但解决这个问题的最佳方法是什么?我在实现removeHigh方法时也遇到了一些问题,该方法旨在从队列中移除最高的元素。

  • 我目前正在尝试实现min heap PQ,但是我在实现的正确性方面遇到了一些问题,我似乎无法找出我做错了什么——它没有输出最低优先级,也没有对它们进行正确排序。 使用以下测试数据: 我得到以下结果: 我希望结果是按升序排列的——起初我认为这可能是因为交换了错误的孩子,但最后一个输出是最大的优先级,所以这没有意义。我花了几个小时试图研究堆优先级队列,但我找不到任何帮助。 以下是CMP要求的更好的代码

  • 注意:我知道可以用比较器创建优先级队列,然后重复调用Add。

  • 问题内容: 总体而言,我正在尝试使用优先级队列来实现Dijkstra的算法。 根据golang-nuts的成员所述,Go中惯用的方法是将堆接口与自定义的基础数据结构一起使用。所以我像这样创建了Node.go和PQueue.go: 和PQueue.go: 和main.go :(动作在SolveMatrix中) 问题是,在编译时我收到错误消息: 注释掉PQ.Push(firstNode)行确实使编译器

  • 在前面的部分中,你了解了称为队列的先进先出数据结构。队列的一个重要变种称为优先级队列。优先级队列的作用就像一个队列,你可以通过从前面删除一个项目来出队。然而,在优先级队列中,队列中的项的逻辑顺序由它们的优先级确定。最高优先级项在队列的前面,最低优先级的项在后面。因此,当你将项排入优先级队列时,新项可能会一直移动到前面。我们将在下一章中研究一些图算法看到优先级队列是有用的数据结构。 你可能想到了几种

  • 我正在开发一个演示Djikstra算法的应用程序,要使用它,我需要在元素的值减少时恢复堆属性。 关于复杂性的问题是,当算法改变一个元素的值时,该元素在用于优先级队列的内部结构(在本例中为堆)中的索引是未知的。因此,我目前需要进行O(n)搜索,以便恢复索引,然后才能对其执行实际的减键。 此外,我不能完全确定操作所需的实际代码。我在这里使用D堆作为优先级队列。伪代码会有所帮助,但我更喜欢Java中的一