Main Page   Class Hierarchy   Compound List   File List   Compound Members  

Heap.java

00001 /*
00002  *  Copyright 2006 Columbia University.
00003  *
00004  *  This file is part of MEAPsoft.
00005  *
00006  *  MEAPsoft is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License version 2 as
00008  *  published by the Free Software Foundation.
00009  *
00010  *  MEAPsoft is distributed in the hope that it will be useful, but
00011  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with MEAPsoft; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00018  *  02110-1301 USA
00019  *
00020  *  See the file "COPYING" for the text of the license.
00021  */
00022 
00023 package com.meapsoft;
00024 
00025 import java.util.Collection;
00026 import java.util.Comparator;
00027 import java.util.Vector;
00028 
00029 // I can't believe that the huge Java API doesn't already include such
00030 // a basic data structure
00031 
00040 public abstract class Heap extends Vector
00041 {
00042     // Comparator to use to compare two elements in this Heap (if this
00043     // is null, assume that all elements are Comparable)
00044     private Comparator comp = null;
00045     // does the current instance obey the heap property?
00046     protected boolean isHeap = true;
00047 
00048     public Heap()
00049     {
00050         super();
00051     }
00052 
00058     public Heap(Comparator c)
00059     {
00060         super();
00061         comp = c;
00062     }
00063 
00064     public Heap(int capacity)
00065     {
00066         super(capacity);
00067     }
00068 
00069     public Heap(Collection c)
00070     {
00071         super();
00072         addAll(c);
00073     }
00074 
00075     public Object remove(int index)
00076     {
00077         if(!isHeap)
00078             rebuildHeap();
00079 
00080         Object o = get(index);
00081 
00082         set(index, get(size()-1));
00083         removeElementAt(size()-1);
00084         heapify(index);
00085 
00086         return o;
00087     }
00088 
00089     public boolean remove(Object o)
00090     {
00091         boolean found = false;
00092         for(int i = 0; i < size(); i++)
00093         {
00094             if(o == null ? get(i) == null : o.equals(get(i)))
00095             {
00096                 found = true;
00097                 remove(i);
00098 
00099                 break;
00100             }
00101         }
00102 
00103         return found;
00104     }
00105 
00106     public boolean add(Object o)
00107     {
00108         if(!isHeap)
00109             rebuildHeap();
00110 
00111         boolean b = super.add(o);
00112 
00113         for(int node = size()-1; node > 0;)
00114         {
00115             int cmp;
00116             int parent = (int)((node-1)/2);
00117 
00118             if(cmp(node, parent) < 0)
00119             {
00120                 // swap them and reheapify
00121                 Object tmp = get(node);
00122                 set(node, get(parent));
00123                 set(parent, tmp);
00124             }
00125 
00126             node = parent;
00127         }
00128 
00129         //System.out.print("\nContents: ");
00130         //for(int x = 0; x < size(); x++)
00131         //    System.out.print(get(x) + " ");
00132         //System.out.println();
00133 
00134         return b;
00135     }
00136 
00137     public boolean addAll(Collection c)
00138     {
00139         boolean b = super.addAll(c);
00140         rebuildHeap();
00141 
00142         return(b);
00143     }
00144 
00152     public void rebuildHeap()
00153     {
00154         // do the whole linear time build-heap thing
00155         for(int i = (int)(size()/2); i >= 0; i--)
00156             heapify(i);
00157 
00158         isHeap = true; 
00159     }
00160 
00167     public void sort()
00168     {
00169         for(int x = size()-1; x > 0; x--)
00170         {
00171             // swap end of heap with the root, then heapify whats
00172             // left.
00173             Object tmp = get(x);
00174             set(x, get(0));
00175             set(0, tmp);
00176 
00177             heapify(0, x);
00178         }           
00179 
00180         // the above code destroys the heap property - the array is
00181         // essentially in reverse sorted order (with respect to the
00182         // first element in the heap (min if MinHeap, max if MaxHeap))
00183         //
00184         // The next call to one of the Heap methods will rebuild the
00185         // heap.
00186         isHeap = false; 
00187     }
00188 
00193     protected int cmp(int node1, int node2)
00194     {
00195         int c = 0; 
00196         if(comp != null)
00197             c = comp.compare(get(node1), get(node2));
00198         else
00199             c = ((Comparable)get(node1)).compareTo(get(node2));
00200 
00201         return c;
00202     }
00203 
00207     private void heapify(int node, int size)
00208     {
00209         if(node > size)
00210             return;
00211 
00212         int left = (node+1)*2-1;
00213         int right = (node+1)*2;
00214 
00215         int minidx = node;
00216         if(left < size && cmp(left, node) < 0)
00217             minidx = left;
00218         if(right < size && cmp(right, node) < 0 && cmp(right, left) < 0)
00219             minidx = right;
00220 
00221         if(minidx != node)
00222         {
00223             // swap them and recurse on the subtree rooted at minidx
00224             Object tmp = get(node);
00225             set(node, get(minidx));
00226             set(minidx, tmp);
00227             heapify(minidx, size);
00228         }
00229     }
00230 
00234     private void heapify(int node)
00235     {
00236         heapify(node, size());
00237     }
00238 }

Generated on Thu May 11 15:04:10 2006 for MEAPsoft by doxygen1.2.18