PriorityQueue基于未排序的数组迭代器

时间:2014-08-18 19:39:56

标签: java iterator priority-queue

我根据未排序的数组编写了自己的priority_queue,因此在O(1)中添加新元素的工作速度很快,但删除具有最大优先级(最小值)的元素在O(N)

中运行缓慢
import java.util.*;

public class PriorityQueue<K extends Comparable> {
    private int index;
    private Comparable[] elements;

    public Object[] getElements() {
        return elements;
    }

    public PriorityQueue(int capacity) {
        if (capacity < 0)
            capacity = 10;
        elements = new Comparable[capacity];
    }

    public PriorityQueue() {
        this(10);
    }

    public boolean isEmpty() {
        return index == 0;
    }

    public int size() {
        return index;
    }

    private void resize() {
        elements = Arrays.copyOf(elements, elements.length * 2);
    }

    public void add(K element) {
        if (index == elements.length)
            resize();

        elements[index++] = element;
    }

    public Comparable remove() {
        if (isEmpty())
            throw new PriorityQueueIsEmptyException("Queue is empty!");

        int priorityIndex = 0;
        for (int i = 1; i < index; i++) {
            if (elements[i].compareTo(elements[priorityIndex]) < 0)
                priorityIndex = i;
        }
        Comparable result = elements[priorityIndex];
        index--;
        elements[priorityIndex] = elements[index];

        return result;
    }

    public Comparable<K> poll() {
        if (isEmpty())
            return null;

        return remove();
    }

    public Comparable element() {
        if (isEmpty())
            throw new PriorityQueueIsEmptyException("Queue is empty!");

        int priorityIndex = 0;
        for (int i = 1; i < index; i++) {
            if (elements[i].compareTo(elements[priorityIndex]) < 0)
                priorityIndex = i;
        }

        return elements[priorityIndex];
    }

    public Comparable peek() {
        if (isEmpty())
            return null;

        return element();
    }

    public Iterator iterator() {
        return new QueueIterator();
    }

    public void print() {
        for (int i = 0; i < index; i++) {
            System.out.print(elements[i] + " --> ");
        }
        System.out.println();
    }

    private class QueueIterator implements Iterator {

        // we keep list of indexes of elements that have been taken allready by method        next()
        // we keep it in order not to check elements with such indexes when we are founding new min element 
        // sorry for my eng
        private List<Integer> usedIndexes;

        private Comparable next;

        public QueueIterator() {
            usedIndexes = new ArrayList<Integer>();
        }

        private Comparable min(Comparable[] elements, int from, int to, List<Integer> usedIndexes) {

            // trick to assign min value
            // we cannot start from the first element cause he might be minimal allready
            int startIndex = from;
            for (int i = from; i <= to; i++) {
                if (!usedIndexes.contains(i)) {
                    startIndex = i;
                    break;
                }
            }

            Comparable min = elements[startIndex];
            int minIndex = startIndex;

            for (int i = from; i <= to; i++) {
                if (!usedIndexes.contains(i) && elements[i].compareTo(min) < 0) {
                    min = elements[i];
                    minIndex = i;
                }
            }
            usedIndexes.add(minIndex);
            return min;
        }

        @Override
        public boolean hasNext() {
            return usedIndexes.size() == index;
        }

        @Override
        public Comparable next() {
            if (isEmpty())
                throw new NoSuchElementException();
            next = min(elements, 0, index - 1, usedIndexes);
            return next;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

public class PriorityQueueIsEmptyException extends RuntimeException {

    PriorityQueueIsEmptyException() {

    }

    PriorityQueueIsEmptyException(String message) {
        super(message);
    }
}

我的问题是: 我做了迭代器吗? 在我看来,这个方法next()不好,它在O(N * N)中工作,我是对的吗? 有没有办法更好地做迭代器?

0 个答案:

没有答案