LAL  7.5.0.1-08ee4f4
HeapSort.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 /*-----------------------------------------------------------------------
21  *
22  * File Name: HeapSort.c
23  *
24  * Author: Creighton, T. D.
25  *
26  *
27  *-----------------------------------------------------------------------*/
28 
29 /* ---------- see Sort.h for doxygen documentation ---------- */
30 
31 #include <string.h>
32 #include <lal/LALStdlib.h>
33 #include <lal/AVFactories.h>
34 #include <lal/Sort.h>
35 
36 /* helpful macros for generic routines */
37 /* copy element j of array y to element i of array x; elements have size s */
38 #define COPY(x,i,y,j,s) (memcpy((char*)(x)+(i)*(s),(char*)(y)+(j)*(s),(s)))
39 /* compare element j of array y with element i of array x; elements have size s
40  * use compare function c with params p */
41 #define CMP(x,i,y,j,s,p,c) ((c)((p),(char*)(x)+(i)*(s),(char*)(y)+(j)*(s)))
42 
43 
44 int XLALHeapSort( void *base, UINT4 nobj, UINT4 size, void *params,
45  int (*compar)(void *, const void *, const void *) )
46 {
47  INT4 i, j, k, n = nobj;
48  void *temp;
49 
50  if ( (INT4)size <= 0 )
52  if ( ! base || ! compar )
54 
55  /* 0 or 1 objects are already sorted. */
56  if (n<2)
57  return 0;
58 
59  temp = LALMalloc( size );
60  if ( ! temp )
62 
63  /* Here is the heapsort algorithm. */
64  j=n-1;
65  n >>= 1;
66  while(1){
67  if(n>0)
68  COPY(temp,0,base,--n,size);
69  else{
70  COPY(temp,0,base,j,size);
71  COPY(base,j,base,0,size);
72  if(--j==0){
73  COPY(base,0,temp,0,size);
74  break;
75  }
76  }
77  i=n;
78  k=(n << 1)+1;
79  while(k<=j){
80  if(k<j && CMP(base,k,base,k+1,size,params,compar) < 0)
81  k++;
82  if(CMP(temp,0,base,k,size,params,compar) < 0){
83  COPY(base,i,base,k,size);
84  i=k;
85  k<<=1;
86  k++;
87  }else
88  k=j+1;
89  }
90  COPY(base,i,temp,0,size);
91  }
92 
93  LALFree( temp );
94  return 0;
95 }
96 
97 
98 int XLALHeapIndex( INT4 *indx, void *base, UINT4 nobj, UINT4 size, void *params,
99  int (*compar)(void *, const void *, const void *) )
100 {
101  INT4 i, j, k, n = nobj;
102  INT4 itemp;
103 
104  if ( (INT4)size <= 0 )
106  if ( ! indx || ! base || ! compar )
108 
109  /* Initialize the indx vector */
110  for (i=0;i<n;++i)
111  indx[i]=i;
112 
113  /* 0 or 1 objects are already sorted. */
114  if (n<2)
115  return 0;
116 
117  /* Here is the heapsort algorithm. */
118  j=n-1;
119  n >>= 1;
120 
121  while(1){
122  if(n>0)
123  itemp=indx[--n];
124  else{
125  itemp=indx[j];
126  indx[j]=indx[0];
127  if(--j==0){
128  indx[0]=itemp;
129  break;
130  }
131  }
132  i=n;
133  k=(n << 1)+1;
134  while(k<=j){
135  if(k<j && CMP(base,indx[k],base,indx[k+1],size,params,compar)<0)
136  k++;
137  if(CMP(base,itemp,base,indx[k],size,params,compar)<0){
138  indx[i]=indx[k];
139  i=k;
140  k<<=1;
141  k++;
142  }else
143  k=j+1;
144  }
145  indx[i]=itemp;
146  }
147 
148  return 0;
149 }
150 
151 
152 int XLALHeapRank( INT4 *rank, void *base, UINT4 nobj, UINT4 size, void *params,
153  int (*compar)(void *, const void *, const void *) )
154 {
155  INT4 i, n = nobj;
156  INT4 *indx;
157 
158  if ( (INT4)size <= 0 )
160  if ( ! rank || ! base || ! compar )
162 
163  indx = LALMalloc( nobj * sizeof( *rank ) );
164  if ( ! indx )
166 
167  if ( XLALHeapIndex( indx, base, nobj, size, params, compar ) < 0 )
169 
170  for(i=0;i<n;++i)
171  rank[indx[i]]=i;
172 
173  LALFree( indx );
174  return 0;
175 }
#define COPY(x, i, y, j, s)
Definition: HeapSort.c:38
#define CMP(x, i, y, j, s, p, c)
Definition: HeapSort.c:41
#define LALMalloc(n)
Definition: LALMalloc.h:93
#define LALFree(p)
Definition: LALMalloc.h:96
uint32_t UINT4
Four-byte unsigned integer.
int32_t INT4
Four-byte signed integer.
int XLALHeapSort(void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:44
int XLALHeapRank(INT4 *rank, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:152
int XLALHeapIndex(INT4 *indx, void *base, UINT4 nobj, UINT4 size, void *params, int(*compar)(void *, const void *, const void *))
Definition: HeapSort.c:98
#define XLAL_ERROR(...)
Macro to invoke a failure from a XLAL routine returning an integer.
Definition: XLALError.h:700
@ XLAL_ENOMEM
Memory allocation error.
Definition: XLALError.h:407
@ XLAL_EFAULT
Invalid pointer.
Definition: XLALError.h:408
@ XLAL_EFUNC
Internal function call failed bit: "or" this with existing error number.
Definition: XLALError.h:462
@ XLAL_EINVAL
Invalid argument.
Definition: XLALError.h:409