Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 索引优先级队列的混乱_Java_Algorithm_Priority Queue - Fatal编程技术网

Java 索引优先级队列的混乱

Java 索引优先级队列的混乱,java,algorithm,priority-queue,Java,Algorithm,Priority Queue,我已经了解了优先级队列的概念,但是当涉及到索引优先级队列时,我对一些方法的实现有点困惑,比如change(intk,Item-Item)和delete(inti) 更改(int k,Item Item)是将与k关联的项更改为Item delete(inti)是删除k及其关联项 public void changeKey(int i,Key){ 如果(i=maxN)抛出新的IndexOutOfBoundsException(); 如果(!contains(i))抛出新的NoSuchElementE

我已经了解了优先级队列的概念,但是当涉及到索引优先级队列时,我对一些方法的实现有点困惑,比如change(intk,Item-Item)和delete(inti)

更改(int k,Item Item)是将与k关联的项更改为Item

delete(inti)是删除k及其关联项

public void changeKey(int i,Key){
如果(i<0 | | i>=maxN)抛出新的IndexOutOfBoundsException();
如果(!contains(i))抛出新的NoSuchElementException(“索引不在优先级队列中”);
键[i]=键;
游泳(qp[i]);
水槽(qp[i]);
}
公共作废删除(int i){
如果(i<0 | | i>=maxN)抛出新的IndexOutOfBoundsException();
如果(!contains(i))抛出新的NoSuchElementException(“索引不在优先级队列中”);
int index=qp[i];
exch(指数,n-);
游泳(指数);
汇(指数);
密钥[i]=null;
qp[i]=-1;
}
私人游泳(国际k){
而(k>1&&更大(k/2,k)){
行政会议(k,k/2);
k=k/2;
}
}
专用空接收器(int k){

而(2*k这些是二进制堆上的操作,在您更改密钥时需要执行。优先级队列中的每个“节点”都保留在二进制堆中。当您添加项时,该项需要定位在正确的位置,这样“二进制堆规则”就不会被打破

更改键也会发生同样的情况,您需要更改项在优先级堆中的位置,以便不破坏规则(该项的子项不大于它,该项的父项不小于它)

这个优先级队列是用一个二进制堆实现的,这意味着它是基于二叉树的,这就是为什么在这些方法中可以看到2的除法,因为它需要逐级执行项的上/下操作,这是通过该除法实现的(第一级有一个节点,第二级有两个节点,第三级有四个节点等,每个级别的节点数乘以2)

这篇文章只是对一个庞大而广泛的话题的介绍,我建议多读一些(尤其是“heapify”部分):

一般来说,关键是您只有一种方法可以更改关键点,它同时调用
swim
sink
,因为上一个关键点可能更高或更低。通常使用两种方法来完成此操作:
decreaseKey
increaseKey
,并且这些方法中的每一种都只调用一个-
sink
swim
,因此,您的代码将这两个方法合并为1,这就是它同时调用
sink
swim
的原因。当新键高于旧键时,意味着它需要在堆中向上(
swim
),当新键低于旧键时,它需要向下(
sink


顺便说一句,我的整个帖子都假设我们使用的是最大堆-这意味着根节点有最大值,他的子节点有较小的值等等。还有一个最小堆,它正好相反。

IndexPrioriryQueue(或者你的类名为什么)不是标准类。是否可以共享该类的其余代码?或者您正在使用的API的名称?@Asoub the似乎来自于本书。在主题之外,我认为bubbleUp和bubbleDown是比swim和sink更好的名称
public void changeKey(int i, Key key) {
        if (i < 0 || i >= maxN) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        keys[i] = key;
        swim(qp[i]);
        sink(qp[i]);
    }

public void delete(int i) {
        if (i < 0 || i >= maxN) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new NoSuchElementException("index is not in the priority queue");
        int index = qp[i];
        exch(index, n--);
        swim(index);
        sink(index);
        keys[i] = null;
        qp[i] = -1;
    }

private void swim(int k) {
        while (k > 1 && greater(k/2, k)) {
            exch(k, k/2);
            k = k/2;
        }
    }

    private void sink(int k) {
        while (2*k <= n) {
            int j = 2*k;
            if (j < n && greater(j, j+1)) j++;
            if (!greater(k, j)) break;
            exch(k, j);
            k = j;
        }
    }


private int maxN;        // maximum number of elements on PQ
private int n;           // number of elements on PQ
private int[] pq;        // binary heap using 1-based indexing
private int[] qp;        // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
private Key[] keys;      // keys[i] = priority of i