简体   繁体   English

Java中出队的优先级队列问题

[英]Priority Queue issue with dequeueing in Java

Hi so im working on a project right now and my dequeueing of minimum values first seems to have an issue. 嗨,我正在一个项目上工作,我的最小值最小值出队似乎是一个问题。 it appears to enqueue fine. 似乎可以入队。 punch in 20, 15, 11, 29 it correctly corresponds with 11,20,15,29. 在20、15、11、29中打孔,它正确对应于11,20,15,29。 These numbers correspond with deadlines to be reached. 这些数字与要达到的截止日期相对应。 now, when I want to dequeue the top value, it'll grab the 11 do the operations on it that are needed discard the task with deadline 11. then when I grab the next top value it returns 20 instead of 15. I cant find out why? 现在,当我想出列最高值时,它将抓取11个所需的操作,并丢弃截止日期为11的任务。然后,当我抓取下一个最高值时,它将返回20而不是15。我找不到为什么? Any help would be greatly appreciated! 任何帮助将不胜感激!

import java.util.Comparator;


public class treeCompare implements Comparator<Task> {

    public int compare(Task t1, Task t2) {

        int dead1 = t1.getDeadline();
        int dead2 = t2.getDeadline();

        return dead1 - dead2;

    }


}

    import java.util.ArrayList;
import java.util.Comparator;


public class PriorityQueue<E> implements QueueADT<E> {

    private ArrayList<E> items;
    private int max;
    private Comparator<E> comp;

    public PriorityQueue(Comparator<E> comp, int maxCapacity){
        this.comp = comp;
        this.max = maxCapacity;
        items = new ArrayList<E>();
    }



    public boolean isFull() {
        if(size() == max) return true;
        else return false;
    }


     private void siftUp() {
            int k = items.size() - 1;
            while (k > 0) {
                int p = (k-1)/2;
                E item = items.get(k);
                E parent = items.get(p);

                     if (comp.compare(items.get(k), items.get(p)) < 0) {
                        // swap
                        items.set(k, parent);
                        items.set(p, item);

                        // move up one level
                        k = p;

                } else {
                    break;
                }
            }
        }

        public void enqueue(E item)throws FullQueueException {
            if(isFull()) throw new FullQueueException();
            items.add(item);
            siftUp();
        }


    /**
     * Returns the front item of the queue without removing it.
     * @return the front item of the queue
     * @throws EmptyQueueException
     */
    public E peek() throws EmptyQueueException {
        if(isEmpty()) throw new EmptyQueueException();
        else{
            E item = items.get(0);
            return item;
        }
    }

    private void siftDown() {
        int k = 0;
        int l = 2*k+1;
        while (l < items.size()) {
            int max=l, r=l+1;
            if (r < items.size()) { // there is a right child
                if (comp.compare(items.get(r), items.get(l)) > 0) {
                    max++;
                }
            }
            if (comp.compare(items.get(k), items.get(max)) > 0) {
                    // switch
                    E temp = items.get(k);
                    items.set(k, items.get(max));
                    items.set(max, temp);
                    k = max;
                    l = 2*k+1;
            } else {
                break;
            }
        }
    }

    public E dequeue() throws EmptyQueueException {
        if (items.size() == 0) {
            throw new EmptyQueueException();
        }
        if (items.size() == 1) {
            return items.remove(0);
        }
        E hold = items.get(0);
        items.set(0, items.remove(items.size()-1));
        siftDown();
        return hold;
    }

    public int size() {
        return items.size();
    }

    public boolean isEmpty() {
        return items.isEmpty();

    }



   public String toString() {
       return items.toString();
   }


    public int capacity() {
        return max;
    }

}

The comparision comp.compare(items.get(r), items.get(l)) > 0 in shiftDown() seems to be inverted. 之比较comp.compare(items.get(r), items.get(l)) > 0shiftDown()似乎被反转。

Inverting it (and renaming variable max for clarity) the algorithm seems to work (as far as I've tested). 对其进行反转(并为变量重命名以清楚起见),该算法似乎有效(据我测试)。

    private void siftDown() {
        int k = 0;
        int l = 2*k+1;
        while (l < items.size()) {
            int min=l, r=l+1;
            if (r < items.size()) { // there is a right child
                if (comp.compare(items.get(r), items.get(l)) < 0) {
                    min = r;
                }
            }
            if (comp.compare(items.get(k), items.get(min)) > 0) {
                    // switch
                    E temp = items.get(k);
                    items.set(k, items.get(min));
                    items.set(min, temp);
                    k = min;
                    l = 2*k+1;
            } else {
                break;
            }
        }
    }

If I insert [20, 15, 11, 1, 29, 10, 7, 28, 3, 54, 40, 34, 58] I retrieve [1, 3, 7, 10, 11, 15, 20, 28, 29, 34, 40, 54, 58] which looks nice. 如果我插入[20、15、11、1、29、10、7、28、3、54、40、34、58],我会检索[1、3、7、10、11、15、20、28、29 ,,34,40,54,58],看起来不错。
Hope it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM