/* Soot - a J*va Optimization Framework
* Copyright (C) 2004 Ondrej Lhotak
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package soot.util;
import java.util.*;
/** A heap (priority queue) implementation.
* @author Ondrej Lhotak
*/
public class Heap
{
public interface Keys {
public int key(Object o);
}
final Keys keys;
final ArrayList<Object> list = new ArrayList<Object>();
final HashSet<Object> contents = new HashSet<Object>();
private int size;
public int size() { return size; }
public boolean isEmpty() { return size <= 0; }
public Heap(Keys keys) {
this.keys = keys;
list.add(null);
list.add(null);
}
public boolean contains(Object o) {
return contents.contains(o);
}
public boolean add(Object o) {
if(!contents.add(o)) return false;
insert(o);
return true;
}
private void insert(Object o) {
size++;
int i = size;
while(list.size() <= size) list.add(null);
while( i > 1 && key(parent(i)) > key(o) ) {
list.set(i, list.get(parent(i)));
i = parent(i);
}
list.set(i, o);
}
private int left(int i) { return 2*i; }
private int right(int i) { return 2*i+1; }
private int parent(int i) { return i/2; }
private void heapify(int i) {
int l = left(i);
int r = right(i);
int largest;
if( l <= size && key(l) < key(i) ) {
largest = l;
} else {
largest = i;
}
if( r <= size && key(r) < key(largest) ) {
largest = r;
}
if( largest != i ) {
Object iEdge = list.get(i);
Object largestEdge = list.get(largest);
list.set(i, largestEdge);
list.set(largest, iEdge);
heapify(largest);
}
}
public Object min() {
return list.get(1);
}
public Object removeMin() {
if(size == 0) throw new NoSuchElementException();
Object ret = list.get(1);
contents.remove(ret);
list.set(1, list.get(size));
list.set(size, null);
size--;
heapify(1);
return ret;
}
public void heapify() {
for( int i = size; i > 0; i-- ) heapify(i);
}
private int key(Object o) { return keys.key(o); }
private int key(int i) { return keys.key(list.get(i)); }
}