public class MaxHeap{
 private Elem[] Heap;
 private int size;
 private int n; public MaxHeap(Elem[] h,int num,int max){
  Heap = h;n = num;size = max;buildheap();
 } public int heapSize(){
  return n;
 } public boolean isLeaf(int pos){
  return (pos >= n/2) && (pos < n);
 } public int leftchild(int pos){
  Assert.notFalse(pos < n/2,"Position has no left child");
  return 2 * pos + 1;
 } public int rightchild(int pos){
  Assert.notFalse(pos < (n - 1)/2,"Position has no right child");
  return 2 * pos + 2;
 } public int parent(int pos){
  Assert.notFalse(pos > 0,"Position has no parent");
  return (pos - 1) / 2;
 }
 public void buildheap(){
  for(int i = n/2 - 1;i >= 0;i--) siftdown(i);
 }
 private void siftdown(int pos){
  Assert.notFalse((pos >= 0) && (pos < n),"Illegal heap position");
  while(! isLeaf(pos)){
   int j = leftchild(pos);
   if((j < (n - 1)) && (Heap[j].key() < Heap[j + 1].key()))
    j++;
   if(Heap[pos].key() >= Heap[j].key()) return;
   Dsutil.swap(Heap,pos,j);
   pos = j;
  }
 }
 public void insert(Elem val){
  Assert.notFalse(n < size,"Heap is full");
  int curr = n++;
  Heap[curr] = val;
  while((curr != 0) && (Heap[curr].key() > Heap[parent(curr)].key())){
   Dsutil.swap(Heap,curr,parent(curr));
   curr = parent(curr);
  }
 }
 public Elem removemax(){
  Assert.notFalse(n > 0,"Removing from empty Heap");
  Dsutil.swap(Heap,0,--n);
  if(n != 0)
   siftdown(0);
  return Heap[n];
 }
 public Elem remove(int pos){
  Assert.notFalse((pos > 0) && (pos < n),"Illegal heap position");
  Dsutil.swap(Heap,pos,--n);
  if(n != 0)
   siftdown(pos);
  return Heap[n];
 }
}