VPR-6.0

vpr/SRC/util/heapsort.c

Go to the documentation of this file.
00001 #include "heapsort.h"
00002 
00003 /******************* Subroutines local to heapsort.c ************************/
00004 
00005 static void add_to_sort_heap(int *heap,
00006                              float *sort_values,
00007                              int index,
00008                              int heap_tail);
00009 
00010 static int get_top_of_heap_index(int *heap,
00011                                  float *sort_values,
00012                                  int heap_tail,
00013                                  int start_index);
00014 
00015 
00016 /********************* Subroutine definitions *******************************/
00017 
00018 /** This routine loads sort_index [1..nelem] with nelem values:  the indices  
00019  * of the sort_values [1..nelem] array that lead to sort_values[index] being 
00020  * decreasing as one goes through sort_index.  Sort_values is not changed.   
00021  */
00022 void
00023 heapsort(int *sort_index,
00024          float *sort_values,
00025          int nelem,
00026          int start_index)
00027 {
00028 
00029     int i;
00030 
00031         sort_index-=start_index;
00032         sort_values-=start_index;
00033 
00034 /* Build a heap with the *smallest* element at the top. */
00035 
00036     for(i = 1; i <= nelem; i++)
00037         add_to_sort_heap(sort_index, sort_values, i, i);
00038 
00039 /* Now pull items off the heap, smallest first.  As the heap (in sort_index) *
00040  * shrinks, I store the item pulled off (the smallest) in sort_index,        *
00041  * starting from the end. The heap and the stored smallest values never      *
00042  * overlap, so I get a nice sort-in-place.                                   */
00043 
00044     for(i = nelem; i >= 1; i--)
00045         sort_index[i] = get_top_of_heap_index(sort_index, sort_values, i, start_index);
00046 
00047         sort_index+=start_index;
00048         sort_values+=start_index;
00049 }
00050 
00051 /** Adds element index, with value = sort_values[index] to the heap.          
00052  * Heap_tail is the number of elements in the heap *after* the insert.       
00053  */
00054 static void
00055 add_to_sort_heap(int *heap,
00056                  float *sort_values,
00057                  int index,
00058                  int heap_tail)
00059 {
00060 
00061     unsigned int ifrom, ito;    /* Making these unsigned helps compiler opts. */
00062     int temp;
00063 
00064     heap[heap_tail] = index;
00065     ifrom = heap_tail;
00066     ito = ifrom / 2;
00067 
00068     while(ito >= 1 && sort_values[heap[ifrom]] < sort_values[heap[ito]])
00069         {
00070             temp = heap[ito];
00071             heap[ito] = heap[ifrom];
00072             heap[ifrom] = temp;
00073             ifrom = ito;
00074             ito = ifrom / 2;
00075         }
00076 }
00077 
00078 /** Returns the index of the item at the top of the heap (the smallest one).  
00079  * It then rebuilds the heap.  Heap_tail is the number of items on the heap  
00080  * before the top item is deleted.                                           
00081  */
00082 static int
00083 get_top_of_heap_index(int *heap,
00084                       float *sort_values,
00085                       int heap_tail,
00086                           int start_index)
00087 {
00088 
00089     int index_of_smallest, temp;
00090     unsigned int ifrom, ito, heap_end;
00091 
00092     index_of_smallest = heap[1];
00093     heap[1] = heap[heap_tail];
00094     heap_end = heap_tail - 1;   /* One item deleted. */
00095     ifrom = 1;
00096     ito = 2 * ifrom;
00097 
00098     while(ito <= heap_end)
00099         {
00100             if(sort_values[heap[ito + 1]] < sort_values[heap[ito]])
00101                 ito++;
00102 
00103             if(sort_values[heap[ito]] > sort_values[heap[ifrom]])
00104                 break;
00105 
00106             temp = heap[ito];
00107             heap[ito] = heap[ifrom];
00108             heap[ifrom] = temp;
00109             ifrom = ito;
00110             ito = 2 * ifrom;
00111         }
00112         
00113         /*index must have the start_index subracted to be consistent with the original array*/
00114     return (index_of_smallest - start_index);
00115 }