Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

cs_sort_fi.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "cs.h"
00008 
00009 /********************************************************************************/
00010 /* insertion_sort : sort an array of float + int                                */
00011 
00012 static void isort_floatint( int n , float * ar , int * iar )
00013 {
00014    register int  j , p ;  /* array indices */
00015    register float temp ;  /* a[j] holding place */
00016    register int  itemp ;
00017    register float * a = ar ;
00018    register int  * ia = iar ;
00019 
00020    if( n < 2 ) return ;
00021 
00022    for( j=1 ; j < n ; j++ ){
00023 
00024      if( a[j] < a[j-1] ){   /* out of order */
00025         p    = j ;
00026         temp = a[j] ; itemp = ia[j] ;
00027 
00028        do{
00029            a[p] =  a[p-1] ; /* at this point, a[p-1] > temp, so move it up */
00030           ia[p] = ia[p-1] ;
00031           p-- ;
00032         } while( p > 0 && temp < a[p-1] ) ;
00033 
00034         a[p] = temp ;       /* finally, put temp in its place */
00035        ia[p] = itemp ;
00036      }
00037    }
00038 }
00039 
00040 /********************************************************************************/
00041 /* qsrec : recursive part of quicksort (stack implementation)                   */
00042 
00043 #define QS_STACK  1024  /* stack size */
00044 #define QS_SWAPF(x,y) ( temp=(x),(x)=(y),(y)= temp)
00045 #define QS_SWAPI(i,j) (itemp=(i),(i)=(j),(j)=itemp)
00046 
00047 static void qsrec_floatint( int n , float * ar , int * iar , int cutoff )
00048 {
00049    register int i , j ;           /* scanning indices */
00050    register float temp , pivot ;  /* holding places */
00051    register int  itemp , ipivot ;
00052    register float * a = ar ;
00053    register int  * ia = iar ;
00054 
00055    int left , right , mst , stack[QS_STACK] , nnew ;
00056 
00057    /* return if too short (insertion sort will clean up) */
00058 
00059    if( cutoff < 3 ) cutoff = 3 ;
00060    if( n < cutoff ) return ;
00061 
00062    /* initialize stack to start with whole array */
00063 
00064    stack[0] = 0   ;
00065    stack[1] = n-1 ;
00066    mst      = 2   ;
00067 
00068    /* loop while the stack is nonempty */
00069 
00070    while( mst > 0 ){
00071       right = stack[--mst] ;  /* work on subarray from left -> right */
00072       left  = stack[--mst] ;
00073 
00074       i = ( left + right ) / 2 ;           /* middle of subarray */
00075 
00076       /* sort the left, middle, and right a[]'s */
00077 
00078       if( a[left] > a[i]     ){ QS_SWAPF(a[left] ,a[i]    ); QS_SWAPI(ia[left] ,ia[i]    ); }
00079       if( a[left] > a[right] ){ QS_SWAPF(a[left] ,a[right]); QS_SWAPI(ia[left] ,ia[right]); }
00080       if( a[i] > a[right]    ){ QS_SWAPF(a[right],a[i]    ); QS_SWAPI(ia[right],ia[i]    ); }
00081 
00082       pivot  = a[i] ;                        /* a[i] is the median-of-3 pivot! */
00083       a[i]   = a[right] ;
00084       ipivot = ia[i] ;
00085       ia[i]  = ia[right] ;
00086 
00087       i = left ;                            /* initialize scanning */
00088       j = right ;
00089 
00090       /*----- partition:  move elements bigger than pivot up and elements
00091                           smaller than pivot down, scanning in from ends -----*/
00092 
00093       do{
00094         for( ; a[++i] < pivot ; ) ;  /* scan i up,   until a[i] >= pivot */
00095         for( ; a[--j] > pivot ; ) ;  /* scan j down, until a[j] <= pivot */
00096 
00097         if( j <= i ) break ;         /* if j meets i, quit */
00098 
00099         QS_SWAPF( a[i] , a[j] ) ; QS_SWAPI( ia[i] , ia[j] ) ;
00100       } while( 1 ) ;
00101 
00102       /*----- at this point, the array is partitioned -----*/
00103 
00104       a[right]  = a[i] ;           /*restore the pivot*/
00105       a[i]      = pivot ;
00106       ia[right] = ia[i] ;
00107       ia[i]     = ipivot ;
00108 
00109       /*----- push subarrays [left..i-1] and [i+1..right] onto stack, if big -----*/
00110 
00111       nnew = 0 ;
00112       if( (i-left)  > cutoff ){ stack[mst++] = left ; stack[mst++] = i-1   ; nnew++ ; }
00113       if( (right-i) > cutoff ){ stack[mst++] = i+1  ; stack[mst++] = right ; nnew++ ; }
00114 
00115       /* if just added two subarrays to stack, make sure shorter one comes first */
00116 
00117       if( nnew == 2 && stack[mst-3] - stack[mst-4] > stack[mst-1] - stack[mst-2] ){
00118          QS_SWAPI( stack[mst-4] , stack[mst-2] ) ;
00119          QS_SWAPI( stack[mst-3] , stack[mst-1] ) ;
00120       }
00121 
00122    }  /* end of while stack is non-empty */
00123 
00124 }
00125 
00126 /********************************************************************************/
00127 /* quick_sort :  sort an array partially recursively, and partially insertion   */
00128 
00129 #ifndef QS_CUTOFF
00130 #define QS_CUTOFF 10
00131 #endif
00132 
00133 void qsort_floatint( int n , float * a , int * ia )
00134 {
00135    qsrec_floatint( n , a , ia , QS_CUTOFF ) ;
00136    isort_floatint( n , a , ia ) ;
00137    return ;
00138 }
 

Powered by Plone

This site conforms to the following standards: