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

堆优先级队列实现

陆仲渊
2023-03-14

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

public class HeapPriorityQueue implements PriorityQueue 
{
    protected final static int DEFAULT_SIZE = 10000;

    protected Comparable[] storage;
    protected int currentSize;

    public HeapPriorityQueue () 
    {
        this.storage=new Comparable[DEFAULT_SIZE];
        this.currentSize=0;
    }

    public HeapPriorityQueue(int size)
    {
        this.currentSize=size;
        this.storage=new Comparable[currentSize];
    }

    public int size ()
    {
        return currentSize;
    }

    public boolean isEmpty ( )
    {
        if(currentSize==0)
            return true;
        else
            return false;
    }

    public boolean isFull ( )
    {
        if(currentSize==DEFAULT_SIZE)
            return true;
        else
            return false;
    }

    public Comparable removeHigh () throws HeapEmptyException
    {
        if(isEmpty()) {
            throw new HeapEmptyException();
        }else{
            Comparable[] k = new Comparable[0];
            k.equals(storage[1]);
            storage[1] = storage[currentSize];
            storage[currentSize] = null;
            currentSize--;
            bubbleDown();
            return storage[currentSize];
        }
    }

    public void insert ( Comparable k  ) throws HeapFullException
    {   
        if(isFull()) {
            throw new HeapFullException();
        }
            currentSize++;
            int index = currentSize;
            storage[index] = k;

            bubbleUp();

    }

    protected void bubbleUp ( ) 
    {
        int index = this.currentSize;

        while(parent(index).compareTo(storage[index]) > 0) {
            swapElement(index, parent(index));
            index = parent(index);
        }

    }

    protected void bubbleDown() 
    {
        int index = 1; 
        while (hasLeft(index)) {
            int smaller = leftChild(index);

            if(hasRight(index) && 
                storage[leftChild(index)].compareTo(storage[rightChild(index)])>0) {
                    smaller = rightChild(index);
                }

            if(storage[index].compareTo(storage[smaller]) > 0) {
                swapElement(index, smaller);
            }else{
                break;
            }
        }


    }   

    protected void swapElement ( int p1, int p2 )
    {
        Comparable k = storage[p1];
        storage[p1] = storage[p2];
        storage[p2] = k;

    }

    protected int parent ( int pos )
    {
        if(pos>1)
            return pos;
        else
            return 0;
    }

    protected int leftChild ( int pos )
    {
        return pos*2;
    }

    protected int rightChild ( int pos )
    {   
        return pos*2+1;
    }

    protected boolean hasLeft ( int pos )
    {
        if(leftChild(pos) <= currentSize)
            return true;
        else
            return false;
    }

    protected boolean hasRight ( int pos )
    {
        if(rightChild(pos) <= currentSize)
            return true;
        else
            return false;
    }


}

共有1个答案

桂智志
2023-03-14

大概,一旦交换元素,parent(index)的结果就会改变。尝试

protected void bubbleUp() {
    int index = this.currentSize;
    int pi;
    while((pi = parent(index)).compareTo(storage[index]) > 0) {
        swapElement(index, pi);
        index = pi;
    }
}
 类似资料:
  • 注意:我知道可以用比较器创建优先级队列,然后重复调用Add。

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

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

  • 问题内容: 我正在尝试根据文档中提供的示例实现优先级队列。文件:priorityQueue 简而言之,它看起来像这样(不包括所有内容): 该文件中: 如您所见,在与示例进行比较时,我不使用指针,因为这样做会给我一个编译错误,告诉我我的优先级队列未正确实现接口。 这会给我带来以下问题: 该项目未附加到队列中。 我试图写出队列指针地址,它显示了不同的地址。这就解释了为什么它不起作用,但是切片不是地图长

  • 我不熟悉堆,二进制堆,我试图理解为什么我们需要使用二进制堆实现优先级队列。我还了解到二进制堆的底层数据结构也是一个数组。 所以我的问题是,为什么我们不能使用一个数组,按降序(对于最大堆)或升序(对于最小堆)排序来表示优先级队列?这里我可能错了,但我认为,如果以这种方式实现,findMax、findMin、insert和delete等操作的时间复杂度将几乎保持不变。那么,我们是否可以不使用排序数组来

  • 问题 怎样实现一个按优先级排序的队列? 并且在这个队列上面每次 pop 操作总是返回优先级最高的那个元素 解决方案 下面的类利用 heapq 模块实现了一个简单的优先级队列: import heapq class PriorityQueue: def __init__(self): self._queue = [] self._index = 0