Another way to do it without using a max-heap and a min-heap would be to use a median-heap right away.
In a max-heap, the parent is greater than the children.
We can have a new type of heap where the parent is in the 'middle' of the children - the left child is smaller than the parent and the right child is greater than the parent. All even entries are left children and all odd entries are right children.
The same swim and sink operations which can be performed in a max-heap, can also be performed in this median-heap - with slight modifications. In a typical swim operation in a max-heap, the inserted entry swims up till it is smaller than a parent entry, here in a median-heap, it will swim up till it is lesser than a parent (if it is an odd entry) or greater than a parent (if it is an even entry).
Here's my implementation for this median-heap. I have used an array of Integers for simplicity.
package priorityQueues;
import edu.princeton.cs.algs4.StdOut;
public class MedianInsertDelete {
private Integer[] a;
private int N;
public MedianInsertDelete(int capacity){
// accounts for '0' not being used
this.a = new Integer[capacity+1];
this.N = 0;
}
public void insert(int k){
a[++N] = k;
swim(N);
}
public int delMedian(){
int median = findMedian();
exch(1, N--);
sink(1);
a[N+1] = null;
return median;
}
public int findMedian(){
return a[1];
}
// entry swims up so that its left child is smaller and right is greater
private void swim(int k){
while(even(k) && k>1 && less(k/2,k)){
exch(k, k/2);
if ((N > k) && less (k+1, k/2)) exch(k+1, k/2);
k = k/2;
}
while(!even(k) && (k>1 && !less(k/2,k))){
exch(k, k/2);
if (!less (k-1, k/2)) exch(k-1, k/2);
k = k/2;
}
}
// if the left child is larger or if the right child is smaller, the entry sinks down
private void sink (int k){
while(2*k <= N){
int j = 2*k;
if (j < N && less (j, k)) j++;
if (less(k,j)) break;
exch(k, j);
k = j;
}
}
private boolean even(int i){
if ((i%2) == 0) return true;
else return false;
}
private void exch(int i, int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
private boolean less(int i, int j){
if (a[i] <= a[j]) return true;
else return false;
}
public static void main(String[] args) {
MedianInsertDelete medianInsertDelete = new MedianInsertDelete(10);
for(int i = 1; i <=10; i++){
medianInsertDelete.insert(i);
}
StdOut.println("The median is: " + medianInsertDelete.findMedian());
medianInsertDelete.delMedian();
StdOut.println("Original median deleted. The new median is " + medianInsertDelete.findMedian());
}
}