2 * Implement Heap sort -- direct and indirect sorting
3 * Based on descriptions in Sedgewick "Algorithms in C"
5 * Copyright (C) 1999 Thomas Walter
7 * 18 February 2000: Modified for GSL by Brian Gough
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 3, or (at your option) any
14 * This source is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <gsl/gsl_heapsort.h>
24 static inline void swap (void *base, size_t size, size_t i, size_t j);
25 static inline void downheap (void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare);
27 /* Inline swap function for moving objects around */
30 swap (void *base, size_t size, size_t i, size_t j)
32 register char *a = size * i + (char *) base;
33 register char *b = size * j + (char *) base;
34 register size_t s = size;
48 #define CMP(data,size,j,k) (compare((char *)(data) + (size) * (j), (char *)(data) + (size) * (k)))
51 downheap (void *data, const size_t size, const size_t N, size_t k, gsl_comparison_fn_t compare)
57 if (j < N && CMP (data, size, j, j + 1) < 0)
62 if (CMP (data, size, k, j) < 0)
64 swap (data, size, j, k);
76 gsl_heapsort (void *data, size_t count, size_t size, gsl_comparison_fn_t compare)
78 /* Sort the array in ascending order. This is a true inplace
79 algorithm with N log N operations. Worst case (an already sorted
80 array) is something like 20% slower */
87 return; /* No data to sort */
90 /* We have n_data elements, last element is at 'n_data-1', first at
91 '0' Set N to the last element number. */
96 k++; /* Compensate the first use of 'k--' */
100 downheap (data, size, N, k, compare);
106 /* first swap the elements */
107 swap (data, size, 0, N);
109 /* then process the heap */
112 downheap (data, size, N, 0, compare);