1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #include "cs.h"
8
9 /*****************************************************************************/
10 /* insertion_sort : sort an array of int64_t + int64_t */
11
isort_intint64_t(int64_t n,int64_t * ar,int64_t * iar)12 static void isort_intint64_t( int64_t n , int64_t * ar , int64_t * iar )
13 {
14 register int64_t j , p ; /* array indices */
15 register int64_t temp ; /* a[j] holding place */
16 register int64_t itemp ;
17 register int64_t * a = ar ;
18 register int64_t * ia = iar ;
19
20 if( n < 2 ) return ;
21
22 for( j=1 ; j < n ; j++ ){
23
24 if( a[j] < a[j-1] ){ /* out of order */
25 p = j ;
26 temp = a[j] ; itemp = ia[j] ;
27
28 do{
29 a[p] = a[p-1] ; /* at this point, a[p-1] > temp, so move it up */
30 ia[p] = ia[p-1] ;
31 p-- ;
32 } while( p > 0 && temp < a[p-1] ) ;
33
34 a[p] = temp ; /* finally, put temp in its place */
35 ia[p] = itemp ;
36 }
37 }
38 }
39
40 /********************************************************************************/
41 /* qsrec : recursive part of quicksort (stack implementation) */
42
43 #undef QS_SWAPF
44 #undef QS_SWAPI
45 #define QS_SWAPF(x,y) ( temp=(x),(x)=(y),(y)= temp)
46 #define QS_SWAPI(i,j) (itemp=(i),(i)=(j),(j)=itemp)
47 #ifndef QS_STACK
48 # define QS_STACK 9999
49 #endif
50
qsrec_intint64_t(int64_t n,int64_t * ar,int64_t * iar,int64_t cutoff)51 static void qsrec_intint64_t( int64_t n , int64_t * ar , int64_t * iar , int64_t cutoff )
52 {
53 register int64_t i , j ; /* scanning indices */
54 register int64_t temp , pivot ; /* holding places */
55 register int64_t itemp , ipivot ;
56 register int64_t * a = ar ;
57 register int64_t * ia = iar ;
58
59 int64_t left , right , mst , stack[QS_STACK] , nnew ;
60
61 /* return if too short (insertion sort will clean up) */
62
63 if( cutoff < 3 ) cutoff = 3 ;
64 if( n < cutoff ) return ;
65
66 /* initialize stack to start with whole array */
67
68 stack[0] = 0 ;
69 stack[1] = n-1 ;
70 mst = 2 ;
71
72 /* loop while the stack is nonempty */
73
74 while( mst > 0 ){
75 right = stack[--mst] ; /* work on subarray from left -> right */
76 left = stack[--mst] ;
77
78 i = ( left + right ) / 2 ; /* middle of subarray */
79
80 /* sort the left, middle, and right a[]'s */
81
82 if( a[left] > a[i] ){ QS_SWAPF(a[left] ,a[i] ); QS_SWAPI(ia[left] ,ia[i] ); }
83 if( a[left] > a[right] ){ QS_SWAPF(a[left] ,a[right]); QS_SWAPI(ia[left] ,ia[right]); }
84 if( a[i] > a[right] ){ QS_SWAPF(a[right],a[i] ); QS_SWAPI(ia[right],ia[i] ); }
85
86 pivot = a[i] ; /* a[i] is the median-of-3 pivot! */
87 a[i] = a[right] ;
88 ipivot = ia[i] ;
89 ia[i] = ia[right] ;
90
91 i = left ; /* initialize scanning */
92 j = right ;
93
94 /*----- partition: move elements bigger than pivot up and elements
95 smaller than pivot down, scanning in from ends -----*/
96
97 do{
98 for( ; a[++i] < pivot ; ) ; /* scan i up, until a[i] >= pivot */
99 for( ; a[--j] > pivot ; ) ; /* scan j down, until a[j] <= pivot */
100
101 if( j <= i ) break ; /* if j meets i, quit */
102
103 QS_SWAPF( a[i] , a[j] ) ; QS_SWAPI( ia[i] , ia[j] ) ;
104 } while( 1 ) ;
105
106 /*----- at this point, the array is partitioned -----*/
107
108 a[right] = a[i] ; /*restore the pivot*/
109 a[i] = pivot ;
110 ia[right] = ia[i] ;
111 ia[i] = ipivot ;
112
113 /*----- push subarrays [left..i-1] and [i+1..right] onto stack, if big -----*/
114
115 nnew = 0 ;
116 if( (i-left) > cutoff ){ stack[mst++] = left ; stack[mst++] = i-1 ; nnew++ ; }
117 if( (right-i) > cutoff ){ stack[mst++] = i+1 ; stack[mst++] = right ; nnew++ ; }
118
119 /* if just added two subarrays to stack, make sure shorter one comes first */
120
121 if( nnew == 2 && stack[mst-3] - stack[mst-4] > stack[mst-1] - stack[mst-2] ){
122 QS_SWAPI( stack[mst-4] , stack[mst-2] ) ;
123 QS_SWAPI( stack[mst-3] , stack[mst-1] ) ;
124 }
125
126 } /* end of while stack is non-empty */
127
128 }
129
130 /********************************************************************************/
131 /* quick_sort : sort an array partially recursively, and partially insertion */
132
133 #ifndef QS_CUTOFF
134 #define QS_CUTOFF 10
135 #endif
136
qsort_intint64_t(int64_t n,int64_t * a,int64_t * ia)137 void qsort_intint64_t( int64_t n , int64_t * a , int64_t * ia )
138 {
139 qsrec_intint64_t( n , a , ia , QS_CUTOFF ) ;
140 isort_intint64_t( n , a , ia ) ;
141 return ;
142 }
143