I have a stream of integers, as well as an int k, given by the user. At the end of the program I must print the k highest numbers. I am only allowed to use a priority queue with a capacity of k.
My problem is that when the queue reaches full capacity, the next integer read must replace the lowest in the queue.
How can I keep the queue sorted after insertion, so that I know which int to replace in the next iteration, with O(logn) complexity? I use a swim method (presented bellow), but ,while it will place the new int at the right level, it doesn't keep the queue entirely sorted.
Here's the swim method:
private void swim(int i){
while (i > 1) { //if i root (i==1) return
int p = i/2; //find parent
int result = cmp.compare(heap[i], heap[p]); //compare parent with child
if (result == 1) return; //if child <= parent return
swap(i, p); //else swap and i=p
i = p;
}
}
To make myself more clear here's an example for k = 3.
1: A = 42 / B = null / C = null
2: A = 69 / B= 42 / C = null (69 swims upwards)
3: A = 69 / B= 42 / C = 32
4: A = 69 / B= 42 / C = 32 (no change)
5: A = 104 / B= 42 / C = 69 (104 is inserted replacing 32, then swims upwards)
6: A = 104 / B= 42 / C = 93 (93 is inserted replacing 69, remains there)
First of all, you can't keep the PriorityQueue
in sorted order; it is similar, if not exactly same as a heap data structure.
PriorityQueue
just grantee the top element is the min OR max according to it is min OR max heap.
And also you are getting confused between 2 different problems Sorting elements and Finding K max/min elements.
If you want to Sort elements in a given list of N elements:
You can't get a better running time than O(N*log(N)) using a comparison based sort algorithm.
But, if your case is just Finding K min/max elements from a list of N elements:
You can achieve it in O(N*log(K)) time.
Please check this question once: Finding the first n largest elements in an array