8 KSORT_INIT_GENERIC(int)
12 /**********************************
13 * BEGIN OF PAUL'S IMPLEMENTATION *
14 **********************************/
16 /* Attractive Chaos: I have added inline where necessary. */
19 Copyright (c) 2004 Paul Hsieh
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions are met:
25 Redistributions of source code must retain the above copyright notice,
26 this list of conditions and the following disclaimer.
28 Redistributions in binary form must reproduce the above copyright notice,
29 this list of conditions and the following disclaimer in the documentation
30 and/or other materials provided with the distribution.
32 Neither the name of sorttest nor the names of its contributors may be
33 used to endorse or promote products derived from this software without
34 specific prior written permission.
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
37 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
40 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 POSSIBILITY OF SUCH DAMAGE.
55 icl /O2 /G6 /Qaxi /Qxi /Qip sorttest.c
58 wcl386 /otexan /6r sorttest.c
61 gcc -O3 -mcpu=athlon-xp -march=athlon-xp sorttest.c
64 cl /O2 /Ot /Og /G6 sorttest.c
68 static inline void sort2 (int * numbers
) {
71 if (numbers
[0] <= numbers
[1]) return;
73 numbers
[0] = numbers
[1];
77 static inline void sort3 (int * numbers
) {
80 if (numbers
[0] <= numbers
[1]) {
81 if (numbers
[1] <= numbers
[2]) return;
82 if (numbers
[2] <= numbers
[0]) {
84 numbers
[0] = numbers
[2];
85 numbers
[2] = numbers
[1];
92 if (numbers
[0] <= numbers
[2]) {
93 numbers
[0] = numbers
[1];
97 if (numbers
[2] <= numbers
[1]) {
98 numbers
[0] = numbers
[2];
102 numbers
[0] = numbers
[1];
104 numbers
[1] = numbers
[2];
108 static inline void sort4 (int * num
) {
110 if (num
[0] < num
[1]) {
111 if (num
[1] < num
[2]) {
112 if (num
[1] < num
[3]) {
113 if (num
[2] >= num
[3]) {
120 if (num
[0] < num
[3]) {
130 if (num
[0] < num
[2]) {
131 if (num
[2] < num
[3]) {
132 if (num
[1] < num
[3]) {
141 if (num
[0] < num
[3]) {
151 if (num
[0] < num
[3]) {
154 if (num
[1] < num
[3]) {
162 if (num
[2] < num
[3]) {
184 if (num
[2] >= num
[3]) {
190 if (num
[1] < num
[3]) {
200 if (num
[1] < num
[2]) {
201 if (num
[2] < num
[3]) {
211 if (num
[1] < num
[3]) {
220 if (num
[1] < num
[3]) {
229 if (num
[2] < num
[3]) {
247 static inline void sortAlt2 (int * numbers
, int * altNumbers
) {
248 if (numbers
[0] <= numbers
[1]) {
249 altNumbers
[0] = numbers
[0];
250 altNumbers
[1] = numbers
[1];
252 altNumbers
[0] = numbers
[1];
253 altNumbers
[1] = numbers
[0];
257 static inline void sortAlt3 (int * numbers
, int * altNumbers
) {
258 if (numbers
[0] <= numbers
[1]) {
259 if (numbers
[1] <= numbers
[2]) {
260 altNumbers
[0] = numbers
[0];
261 altNumbers
[1] = numbers
[1];
262 altNumbers
[2] = numbers
[2];
263 } else if (numbers
[2] <= numbers
[0]) {
264 altNumbers
[0] = numbers
[2];
265 altNumbers
[1] = numbers
[0];
266 altNumbers
[2] = numbers
[1];
268 altNumbers
[0] = numbers
[0];
269 altNumbers
[1] = numbers
[2];
270 altNumbers
[2] = numbers
[1];
273 if (numbers
[0] <= numbers
[2]) {
274 altNumbers
[0] = numbers
[1];
275 altNumbers
[1] = numbers
[0];
276 altNumbers
[2] = numbers
[2];
277 } else if (numbers
[2] <= numbers
[1]) {
278 altNumbers
[0] = numbers
[2];
279 altNumbers
[1] = numbers
[1];
280 altNumbers
[2] = numbers
[0];
282 altNumbers
[0] = numbers
[1];
283 altNumbers
[1] = numbers
[2];
284 altNumbers
[2] = numbers
[0];
293 inline void insertSort (int numbers
[], int qty
) {
298 if (qty
== 4) sort4 (numbers
);
299 else if (qty
== 3) sort3 (numbers
);
300 else if (qty
== 2) sort2 (numbers
);
306 for (i
=0; i
< q4
; i
++) {
308 for (j
=i
+1; j
< qty
; j
++) {
309 if (numbers
[j
] < numbers
[idx
]) idx
= j
;
313 numbers
[idx
] = numbers
[i
];
318 sort4 (numbers
+ q4
);
325 /* Assure the heap property for entries from top to last */
326 static void siftDown (int numbers
[], int top
, int last
) {
327 int tmp
= numbers
[top
];
330 while (last
>= (maxIdx
+= maxIdx
)) {
332 /* This is where the comparison occurrs and where a sufficiently
333 good compiler can use a computed conditional result rather
334 than using control logic. */
335 if (maxIdx
!= last
&& numbers
[maxIdx
] < numbers
[maxIdx
+ 1]) maxIdx
++;
337 if (tmp
>= numbers
[maxIdx
]) break;
338 numbers
[top
] = numbers
[maxIdx
];
344 /* Peel off the top siftDown operation since its parameters are trivial to
345 fill in directly (and this saves us some moves.) */
346 static void siftDown0 (int numbers
[], int last
) {
349 if (numbers
[0] < numbers
[1]) {
351 numbers
[1] = numbers
[0];
352 siftDown (numbers
, 1, last
);
356 numbers
[0] = numbers
[last
];
360 void heapSort (int numbers
[], int qty
) {
364 if (qty
== 4) sort4 (numbers
);
365 else if (qty
== 3) sort3 (numbers
);
366 else if (qty
== 2) sort2 (numbers
);
371 /* Enforce the heap property for each position in the tree */
372 for ( qty
--; i
> 0; i
--) siftDown (numbers
, i
, qty
);
373 for (i
= qty
; i
> 0; i
--) siftDown0 (numbers
, i
);
380 static int medianOf3 (int * numbers
, int i
, int j
) {
383 if (numbers
[0] <= numbers
[i
]) {
384 if (numbers
[j
] <= numbers
[0]) return numbers
[0]; /* j 0 i */
385 if (numbers
[i
] <= numbers
[j
]) j
= i
; /* 0 i j */
388 if (numbers
[0] <= numbers
[j
]) return numbers
[0]; /* i 0 j */
389 if (numbers
[j
] <= numbers
[i
]) j
= i
; /* j i 0 */
393 numbers
[j
] = numbers
[0];
398 static void quickSortRecurse (int * numbers
, int left
, int right
) {
399 int pivot
, lTmp
, rTmp
;
403 #if defined(__GNUC__)
404 if (right
<= left
+ 8) {
405 insertSort (numbers
+ left
, right
- left
+ 1);
409 if (right
<= left
+ 3) {
410 if (right
== left
+ 1) {
411 sort2 (numbers
+ left
);
412 } else if (right
== left
+ 2) {
413 sort3 (numbers
+ left
);
414 } else if (right
== left
+ 3) {
415 sort4 (numbers
+ left
);
424 pivot
= medianOf3 (numbers
+ left
, (right
-left
) >> 1, right
-1-left
);
430 if (left
>= right
) goto QEnd
;
432 } while (numbers
[right
] > pivot
);
433 numbers
[left
] = numbers
[right
];
440 } while (numbers
[ left
] < pivot
);
441 numbers
[right
] = numbers
[left
];
444 numbers
[left
] = pivot
;
446 /* Only recurse the smaller partition */
448 if (left
-1 - lTmp
<= rTmp
- left
- 1) {
449 if (lTmp
< left
) quickSortRecurse (numbers
, lTmp
, left
-1);
451 /* Set up for larger partition */
455 if (rTmp
> left
) quickSortRecurse (numbers
, left
+1, rTmp
);
457 /* Set up for larger partition */
462 /* Rerun with larger partition (recursion not required.) */
466 void quickSort (int numbers
[], int qty
) {
468 quickSortRecurse (numbers
, 0, qty
- 1);
475 static void mergesortInPlace (int * numbers
, int * altNumbers
, int qty
);
477 /* Perform mergesort, but store results in altNumbers */
479 static void mergesortExchange (int * numbers
, int * altNumbers
, int qty
) {
483 sortAlt2 (numbers
, altNumbers
);
487 sortAlt3 (numbers
, altNumbers
);
493 mergesortInPlace (numbers
, altNumbers
, half
);
494 mergesortInPlace (numbers
+ half
, altNumbers
, qty
- half
);
498 for (i
=0; i
< qty
; i
++) {
499 if (i1
>= qty
|| (i0
< half
&& numbers
[i0
] < numbers
[i1
])) {
500 altNumbers
[i
] = numbers
[i0
];
503 altNumbers
[i
] = numbers
[i1
];
509 /* Perform mergesort and store results in numbers */
511 static void mergesortInPlace (int * numbers
, int * altNumbers
, int qty
) {
529 insertSort (numbers
, qty
);
536 mergesortExchange (numbers
, altNumbers
, half
);
537 mergesortExchange (numbers
+ half
, altNumbers
+ half
, qty
- half
);
541 for (i
=0; i
< qty
; i
++) {
542 if (i1
>= qty
|| (i0
< half
&& altNumbers
[i0
] < altNumbers
[i1
])) {
543 numbers
[i
] = altNumbers
[i0
];
546 numbers
[i
] = altNumbers
[i1
];
554 void mergeSort (int numbers
[], int qty
) {
558 insertSort (numbers
, qty
);
562 tmpArray
= (int *) malloc (qty
* sizeof (int));
563 mergesortInPlace (numbers
, tmpArray
, qty
);
567 /********************************
568 * END OF PAUL'S IMPLEMENTATION *
569 ********************************/
571 /*************************************************
572 *** Implementation 1: faster on sorted arrays ***
573 *************************************************/
575 #define rstype_t unsigned
578 #define RS_MIN_SIZE 64
584 void rs_sort(rstype_t
*beg
, rstype_t
*end
, int n_bits
, int s
)
587 int size
= 1<<n_bits
, m
= size
- 1;
588 rsbucket_t
*k
, b
[size
], *be
= b
+ size
;
590 for (k
= b
; k
!= be
; ++k
) k
->b
= k
->e
= beg
;
591 for (i
= beg
; i
!= end
; ++i
) ++b
[rskey(*i
)>>s
&m
].e
;
592 for (k
= b
+ 1; k
!= be
; ++k
)
593 k
->e
+= (k
-1)->e
- beg
, k
->b
= (k
-1)->e
;
594 for (k
= b
; k
!= be
;) {
597 if ((l
= b
+ (rskey(*k
->b
)>>s
&m
)) != k
) {
598 rstype_t tmp
= *k
->b
, swap
;
600 swap
= tmp
; tmp
= *l
->b
; *l
->b
++ = swap
;
601 l
= b
+ (rskey(tmp
)>>s
&m
);
607 for (b
->b
= beg
, k
= b
+ 1; k
!= be
; ++k
) k
->b
= (k
-1)->e
;
609 s
= s
> n_bits
? s
- n_bits
: 0;
610 for (k
= b
; k
!= be
; ++k
)
611 if (k
->e
- k
->b
> RS_MIN_SIZE
) rs_sort(k
->b
, k
->e
, n_bits
, s
);
612 else if (k
->e
- k
->b
> 1)
613 for (i
= k
->b
+ 1; i
< k
->e
; ++i
)
614 if (rskey(*i
) < rskey(*(i
- 1))) {
615 rstype_t
*j
, tmp
= *i
;
616 for (j
= i
; j
> k
->b
&& rskey(tmp
) < rskey(*(j
-1)); --j
)
623 /*************************************************
624 *** Implementation 2: faster on random arrays ***
625 *************************************************/
627 static inline void rs_insertsort(rstype_t
*s
, rstype_t
*t
)
630 for (i
= s
+ 1; i
< t
; ++i
) {
631 if (rskey(*i
) < rskey(*(i
- 1))) {
632 rstype_t
*j
, tmp
= *i
;
633 for (j
= i
; j
> s
&& rskey(tmp
) < rskey(*(j
-1)); --j
)
640 void rs_sort2(rstype_t *beg, rstype_t *end, int n_bits, int s)
642 int j, size = 1<<n_bits, m = size - 1;
643 unsigned long c[size];
644 rstype_t *i, *b[size], *e[size];
646 for (j = 0; j < size; ++j) c[j] = 0;
647 for (i = beg; i != end; ++i) ++c[rskey(*i)>>s&m];
649 for (j = 1; j != size; ++j) b[j] = e[j] = b[j - 1] + c[j - 1];
650 for (i = beg, j = 0; i != end;) {
651 rstype_t tmp = *i, swap;
655 if (e[x] == i) break;
656 swap = tmp; tmp = *e[x]; *e[x]++ = swap;
660 while (j != size && i >= b[j]) ++j;
661 while (j != size && e[j-1] == b[j]) ++j;
662 if (i < e[j-1]) i = e[j-1];
665 s = s > n_bits? s - n_bits : 0;
666 for (j = 0; j < size; ++j) {
667 if (c[j] >= RS_MIN_SIZE) rs_sort2(b[j], e[j], n_bits, s);
668 else if (c[j] >= 2) rs_insertsort(b[j], e[j]);
673 void radix_sort(unsigned *array
, int offset
, int end
, int shift
) {
674 int x
, y
, value
, temp
;
675 int last
[256] = { 0 }, pointer
[256];
677 for (x
=offset
; x
<end
; ++x
) {
678 ++last
[(array
[x
] >> shift
) & 0xFF];
683 for (x
=1; x
<256; ++x
) {
684 pointer
[x
] = last
[x
-1];
685 last
[x
] += last
[x
-1];
688 for (x
=0; x
<256; ++x
) {
689 while (pointer
[x
] != last
[x
]) {
690 value
= array
[pointer
[x
]];
691 y
= (value
>> shift
) & 0xFF;
693 temp
= array
[pointer
[y
]];
694 array
[pointer
[y
]++] = value
;
696 y
= (value
>> shift
) & 0xFF;
698 array
[pointer
[x
]++] = value
;
704 for (x
=0; x
<256; ++x
) {
705 temp
= x
> 0 ? pointer
[x
] - pointer
[x
-1] : pointer
[0] - offset
;
707 radix_sort(array
, pointer
[x
] - temp
, pointer
[x
], shift
);
708 } else if (temp
> 1) rs_insertsort(array
+ pointer
[x
] - temp
, array
+ pointer
[x
]);
712 /*************************
713 *** END OF RADIX SORT ***
714 *************************/
716 template< class _Type
, unsigned long PowerOfTwoRadix
, unsigned long Log2ofPowerOfTwoRadix
, long Threshold
>
717 inline void _RadixSort_Unsigned_PowerOf2Radix_1( _Type
* a
, long last
, _Type bitMask
, unsigned long shiftRightAmount
)
719 const unsigned long numberOfBins
= PowerOfTwoRadix
;
720 unsigned long count
[ numberOfBins
];
721 for( unsigned long i
= 0; i
< numberOfBins
; i
++ )
723 for ( long _current
= 0; _current
<= last
; _current
++ ) // Scan the array and count the number of times each value appears
725 unsigned long digit
= (unsigned long)(( a
[ _current
] & bitMask
) >> shiftRightAmount
); // extract the digit we are sorting based on
728 long startOfBin
[ numberOfBins
], endOfBin
[ numberOfBins
], nextBin
;
729 startOfBin
[ 0 ] = endOfBin
[ 0 ] = nextBin
= 0;
730 for( unsigned long i
= 1; i
< numberOfBins
; i
++ )
731 startOfBin
[ i
] = endOfBin
[ i
] = startOfBin
[ i
- 1 ] + count
[ i
- 1 ];
732 for ( long _current
= 0; _current
<= last
; )
735 _Type tmp
= a
[ _current
]; // get the compiler to recognize that a register can be used for the loop instead of a[_current] memory location
737 digit
= (unsigned long)(( tmp
& bitMask
) >> shiftRightAmount
); // extract the digit we are sorting based on
738 if ( endOfBin
[ digit
] == _current
)
741 //_swap( tmp, a[ endOfBin[ digit ] ] );
742 tmp2
= a
[endOfBin
[digit
]]; a
[endOfBin
[digit
]] = tmp
; tmp
= tmp2
;
746 endOfBin
[ digit
]++; // leave the element at its location and grow the bin
747 _current
++; // advance the current pointer to the next element
748 while( _current
>= startOfBin
[ nextBin
] && nextBin
< numberOfBins
)
750 while( endOfBin
[ nextBin
- 1 ] == startOfBin
[ nextBin
] && nextBin
< numberOfBins
)
752 if ( _current
< endOfBin
[ nextBin
- 1 ] )
753 _current
= endOfBin
[ nextBin
- 1 ];
755 bitMask
>>= Log2ofPowerOfTwoRadix
;
756 if ( bitMask
!= 0 ) // end recursion when all the bits have been processes
758 if ( shiftRightAmount
>= Log2ofPowerOfTwoRadix
) shiftRightAmount
-= Log2ofPowerOfTwoRadix
;
759 else shiftRightAmount
= 0;
760 for( unsigned long i
= 0; i
< numberOfBins
; i
++ )
762 long numberOfElements
= endOfBin
[ i
] - startOfBin
[ i
];
763 if ( numberOfElements
>= Threshold
) // endOfBin actually points to one beyond the bin
764 _RadixSort_Unsigned_PowerOf2Radix_1
< _Type
, PowerOfTwoRadix
, Log2ofPowerOfTwoRadix
, Threshold
>( &a
[ startOfBin
[ i
]], numberOfElements
- 1, bitMask
, shiftRightAmount
);
765 else if ( numberOfElements
>= 2 )
766 rs_insertsort(&a
[ startOfBin
[ i
]], &a
[ endOfBin
[ i
]]);
770 inline void RadixSortInPlace_HybridUnsigned_Radix256( unsigned* a
, unsigned long a_size
)
772 if ( a_size
< 2 ) return;
773 unsigned long bitMask
= 0xFF000000; // bitMask controls how many bits we process at a time
774 unsigned long shiftRightAmount
= 24;
776 _RadixSort_Unsigned_PowerOf2Radix_1
<unsigned, 256, 8, 32>(a
, a_size
- 1, bitMask
, shiftRightAmount
);
778 rs_insertsort(a
, a
+ a_size
);
782 inline int operator() (int a
, int b
) const {
783 return a
< b
? -1 : a
> b
? 1 : 0;
787 int compare_int(int a
, int b
)
789 return a
< b
? -1 : a
> b
? 1 : 0;
791 int compare(const void *a
, const void *b
)
793 return *((int*)a
) - *((int*)b
);
796 int main(int argc
, char *argv
[])
801 if (argc
== 1) fprintf(stderr
, "Usage: %s [%d]\n", argv
[0], N
);
802 if (argc
> 1) N
= atoi(argv
[1]);
803 temp
= (int*)malloc(sizeof(int) * N
);
804 array
= (int*)malloc(sizeof(int) * N
);
807 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
809 rs_sort((unsigned*)array
, (unsigned*)array
+ N
, 8, 24);
811 fprintf(stderr
, "radix sort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
812 for (i
= 0; i
< N
-1; ++i
) {
813 if (array
[i
] > array
[i
+1]) {
814 fprintf(stderr
, "Bug in radix sort!\n");
819 rs_sort((unsigned*)array
, (unsigned*)array
+ N
, 8, 24);
821 fprintf(stderr
, "radix sort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
824 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
826 RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array
, N
);
827 // radix_sort((unsigned*)array, 0, N, 24);
829 fprintf(stderr
, "vd's radix sort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
830 for (i
= 0; i
< N
-1; ++i
) {
831 if (array
[i
] > array
[i
+1]) {
832 fprintf(stderr
, "Bug in radix sort!\n");
837 RadixSortInPlace_HybridUnsigned_Radix256((unsigned*)array
, N
);
838 // radix_sort((unsigned*)array, 0, N, 24);
840 fprintf(stderr
, "vd's radix sort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
843 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
845 sort(array
, array
+N
);
847 fprintf(stderr
, "STL introsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
849 sort(array
, array
+N
);
851 fprintf(stderr
, "STL introsort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
854 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
856 stable_sort(array
, array
+N
);
858 fprintf(stderr
, "STL stablesort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
860 stable_sort(array
, array
+N
);
862 fprintf(stderr
, "STL stablesort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
865 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
867 make_heap(array
, array
+N
);
868 sort_heap(array
, array
+N
);
870 fprintf(stderr
, "STL heapsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
871 for (i
= 0; i
< N
-1; ++i
) {
872 if (array
[i
] > array
[i
+1]) {
873 fprintf(stderr
, "Bug in heap_sort!\n");
878 make_heap(array
, array
+N
);
879 sort_heap(array
, array
+N
);
881 fprintf(stderr
, "STL heapsort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
884 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
886 ks_combsort(int, N
, array
);
888 fprintf(stderr
, "combsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
889 for (i
= 0; i
< N
-1; ++i
) {
890 if (array
[i
] > array
[i
+1]) {
891 fprintf(stderr
, "Bug in combsort!\n");
897 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
899 qsort(array
, N
, sizeof(int), compare
);
901 fprintf(stderr
, "libc qsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
904 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
906 ks_introsort(int, N
, array
);
908 fprintf(stderr
, "my introsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
909 for (i
= 0; i
< N
-1; ++i
) {
910 if (array
[i
] > array
[i
+1]) {
911 fprintf(stderr
, "Bug in intro_sort!\n");
916 ks_introsort(int, N
, array
);
918 fprintf(stderr
, "introsort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
921 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
923 ks_mergesort(int, N
, array
, 0);
925 fprintf(stderr
, "iterative mergesort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
926 for (i
= 0; i
< N
-1; ++i
) {
927 if (array
[i
] > array
[i
+1]) {
928 fprintf(stderr
, "Bug in merge_sort!\n");
933 ks_mergesort(int, N
, array
, 0);
935 fprintf(stderr
, "iterative mergesort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
938 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
940 ks_heapmake(int, N
, array
);
941 ks_heapsort(int, N
, array
);
943 fprintf(stderr
, "my heapsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
944 for (i
= 0; i
< N
-1; ++i
) {
945 if (array
[i
] > array
[i
+1]) {
946 fprintf(stderr
, "Bug in heap_sort!\n");
951 ks_heapmake(int, N
, array
);
952 ks_heapsort(int, N
, array
);
954 fprintf(stderr
, "heapsort (sorted): %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
957 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
961 fprintf(stderr
, "Paul's heapsort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
962 for (i
= 0; i
< N
-1; ++i
) {
963 if (array
[i
] > array
[i
+1]) {
964 fprintf(stderr
, "Bug in intro_sort!\n");
970 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
974 fprintf(stderr
, "Paul's quicksort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
975 for (i
= 0; i
< N
-1; ++i
) {
976 if (array
[i
] > array
[i
+1]) {
977 fprintf(stderr
, "Bug in intro_sort!\n");
983 for (i
= 0; i
< N
; ++i
) array
[i
] = (int)lrand48();
987 fprintf(stderr
, "Paul's mergesort: %.3lf\n", (double)(t2
-t1
)/CLOCKS_PER_SEC
);
988 for (i
= 0; i
< N
-1; ++i
) {
989 if (array
[i
] > array
[i
+1]) {
990 fprintf(stderr
, "Bug in intro_sort!\n");
995 free(array
); free(temp
);