Yet Another eXchange Tool  DO_NOT_EDIT_HERE
quicksort.c
Go to the documentation of this file.
1 
23 /*
24  * Keywords:
25  * Maintainer: Jörg Behrens <behrens@dkrz.de>
26  * Moritz Hanke <hanke@dkrz.de>
27  * Thomas Jahns <jahns@dkrz.de>
28  * URL: https://doc.redmine.dkrz.de/yaxt/html/
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions are
32  * met:
33  *
34  * Redistributions of source code must retain the above copyright notice,
35  * this list of conditions and the following disclaimer.
36  *
37  * Redistributions in binary form must reproduce the above copyright
38  * notice, this list of conditions and the following disclaimer in the
39  * documentation and/or other materials provided with the distribution.
40  *
41  * Neither the name of the DKRZ GmbH nor the names of its contributors
42  * may be used to endorse or promote products derived from this software
43  * without specific prior written permission.
44  *
45  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
46  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
48  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
49  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
50  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
52  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
53  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56  */
57 
58 #ifdef HAVE_CONFIG_H
59 #include <config.h>
60 #endif
61 
62 #include <stdbool.h>
63 #include <stddef.h>
64 #include <stdlib.h>
65 
66 #include "xt/quicksort.h"
67 #include "core/ppm_xfuncs.h"
68 
69 #define SORT_TYPE idxpos_type
70 #define SORT_TYPE_SUFFIX idxpos
71 #define SORT_TYPE_CMP_LT(a,b) ((a).idx < (b).idx || ((a).idx == (b).idx && (a).pos < (b).pos))
72 #define SORT_TYPE_CMP_LE(a,b) ((a).idx < (b).idx || ((a).idx == (b).idx && (a).pos <= (b).pos))
73 #define SORT_TYPE_CMP_EQ(a,b) ((a).idx == (b).idx && (a).pos == (b).pos)
74 #include "xt_quicksort_base.h"
75 
76 
77 void xt_quicksort_index(Xt_int * v_idx, int n, int * v_pos, int reset_pos) {
78 
79  enum { pointer_inc = 64 };
80  unsigned pointer_size;
81 
82  int * stackl;
83  int * stackr;
84 
85  int i, j, k, l, r;
86  unsigned s;
87  Xt_int w_idx, x_idx;
88  int w_pos, x_pos;
89 
90  /* Initialization */
91  int *v_pos_orig = v_pos;
92 
93  if (!v_pos) v_pos = malloc((size_t)n * sizeof(v_pos[0]));
94 
95  if (v_pos != v_pos_orig || reset_pos) {
96  for(i=0; i<n; i++) {
97  v_pos[i] = i;
98  }
99  }
100 
101  pointer_size = pointer_inc;
102 
103  stackl = xmalloc((size_t)pointer_size * sizeof(stackl[0]));
104  stackr = xmalloc((size_t)pointer_size * sizeof(stackr[0]));
105 
106  s = 1;
107  stackl[0] = 0;
108  stackr[0] = n-1;
109 
110  /* Start sorting
111 
112  ... keep taking the top request from the stack until s = 0.
113 
114  */
115 
116  while ( s > 0 ) {
117 
118  --s;
119  l = stackl[s];
120  r = stackr[s];
121 
122  /* ... keep splitting a[l], ... ,a[r] until l>= r. */
123 
124  while ( l < r ) {
125 
126  i = l;
127  j = r;
128  k = (l+r) / 2;
129  x_idx = v_idx[k];
130  x_pos = v_pos[k];
131 
132  /* Search from lower end */
133 
134  while(1) {
135  while(1)
136  if ((v_idx[i] < x_idx) || (v_idx[i] == x_idx && v_pos[i] < x_pos))
137  i = i + 1;
138  else
139  break;
140 
141  /* Search from upper end */
142 
143  while(1)
144  if ((x_idx < v_idx[j]) || (x_idx == v_idx[j] && x_pos < v_pos[j]))
145  j = j - 1;
146  else
147  break;
148 
149  /* Swap positions i & j */
150 
151  if ( i <= j ) {
152 
153  w_idx = v_idx[i];
154  v_idx[i] = v_idx[j];
155  v_idx[j] = w_idx;
156 
157  w_pos = v_pos[i];
158  v_pos[i] = v_pos[j];
159  v_pos[j] = w_pos;
160 
161  i = i + 1;
162  j = j - 1;
163 
164  if ( i > j ) break;
165  } else
166  break;
167  }
168 
169  if ( j-l >= r-i ) {
170 
171  if ( l < j ) {
172 
173  if ( s >= pointer_size ) {
174  pointer_size = pointer_size + pointer_inc;
175  stackl = xrealloc(stackl, (size_t)pointer_size * sizeof(stackl[0]));
176  stackr = xrealloc(stackr, (size_t)pointer_size * sizeof(stackr[0]));
177  }
178 
179  stackl[s] = l;
180  stackr[s] = j;
181  ++s;
182  }
183  l = i;
184  } else {
185 
186  if ( i < r ) {
187 
188  if ( s >= pointer_size ) {
189  pointer_size = pointer_size + pointer_inc;
190  stackl = xrealloc(stackl, (size_t)pointer_size * sizeof(stackl[0]));
191  stackr = xrealloc(stackr, (size_t)pointer_size * sizeof(stackr[0]));
192  }
193 
194  stackl[s] = i;
195  stackr[s] = r;
196  ++s;
197  }
198  r = j;
199  }
200  } /* ( l < r ) */
201  } /* ( s /= 0 ) */
202 
203  free(stackl);
204  free(stackr);
205  if (v_pos != v_pos_orig) free(v_pos);
206 }
207 
208 #undef SORT_TYPE
209 #undef SORT_TYPE_SUFFIX
210 #undef SORT_TYPE_CMP_LT
211 #undef SORT_TYPE_CMP_LE
212 #undef SORT_TYPE_CMP_EQ
213 #define SORT_TYPE int
214 #define SORT_TYPE_SUFFIX int
215 #define SORT_TYPE_CMP_LT(a,b) (a < b)
216 #define SORT_TYPE_CMP_LE(a,b) (a <= b)
217 #define SORT_TYPE_CMP_EQ(a,b) (a == b)
218 #include "xt_quicksort_base.h"
219 
220 
221 /*
222  * Local Variables:
223  * c-basic-offset: 2
224  * coding: utf-8
225  * indent-tabs-mode: nil
226  * show-trailing-whitespace: t
227  * require-trailing-newline: t
228  * End:
229  */
add versions of standard API functions not returning on error
#define xrealloc(ptr, size)
Definition: ppm_xfuncs.h:67
XT_INT Xt_int
Definition: xt_core.h:68
macros to create quicksort implementations
void xt_quicksort_index(Xt_int *v_idx, int n, int *v_pos, int reset_pos)
Definition: quicksort.c:77
quicksort declaration
#define xmalloc(size)
Definition: ppm_xfuncs.h:66