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

时间:2014-03-29 18:49:22

标签: java heap priority-queue min

嗨,所以我现在正在开展一个项目,我的最低价值首先出现似乎有问题。它看起来很好。在20,15,11,29中打孔它正确对应11,20,15,29。这些数字符合要达到的最后期限。现在,当我想要将最高值出列时,它会抓住11对它做的操作需要在截止日期11之前丢弃任务。然后当我抓住下一个最高值时它返回20而不是15.我无法找到为什么?任何帮助将不胜感激!

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;
    }

}

1 个答案:

答案 0 :(得分:0)

comp.compare(items.get(r), items.get(l)) > 0中的比较shiftDown()似乎已被颠倒。

反转它(并为了清晰起见重命名变量max)算法似乎有效(据我测试过)。

    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;
            }
        }
    }

如果我插入[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]看起来不错 希望它有所帮助!