Subversion Repositories Kolibri OS

Rev

Rev 9013 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9013 Rev 9765
Line 50... Line 50...
50
 * and cleaning up with an insertion sort (in our caller) is a huge win.
50
 * and cleaning up with an insertion sort (in our caller) is a huge win.
51
 * All data swaps are done in-line, which is space-losing but time-saving.
51
 * All data swaps are done in-line, which is space-losing but time-saving.
52
 * (And there are only three places where this is done).
52
 * (And there are only three places where this is done).
53
 */
53
 */
Line 54... Line -...
54
 
-
 
55
static void
54
 
56
qst(char *base, char *max)
55
static void qst(char* base, char* max)
57
{
56
{
58
  char c, *i, *j, *jj;
57
    char c, *i, *j, *jj;
59
  int ii;
58
    int ii;
60
  char *mid, *tmp;
59
    char *mid, *tmp;
Line 70... Line 69...
70
   * prefer the middle, then the first in case of ties.
69
     * prefer the middle, then the first in case of ties.
71
   */
70
     */
72
  lo = max - base;		/* number of elements as chars */
71
    lo = max - base; /* number of elements as chars */
73
  do	{
72
    do {
74
    mid = i = base + qsz * ((lo / qsz) >> 1);
73
        mid = i = base + qsz * ((lo / qsz) >> 1);
75
    if (lo >= mthresh)
74
        if (lo >= mthresh) {
76
    {
-
 
77
      j = (qcmp((jj = base), i) > 0 ? jj : i);
75
            j = (qcmp((jj = base), i) > 0 ? jj : i);
78
      if (qcmp(j, (tmp = max - qsz)) > 0)
76
            if (qcmp(j, (tmp = max - qsz)) > 0) {
79
      {
-
 
80
	/* switch to first loser */
77
                /* switch to first loser */
81
	j = (j == jj ? i : jj);
78
                j = (j == jj ? i : jj);
82
	if (qcmp(j, tmp) < 0)
79
                if (qcmp(j, tmp) < 0)
83
	  j = tmp;
80
                    j = tmp;
84
      }
81
            }
85
      if (j != i)
82
            if (j != i) {
86
      {
-
 
87
	ii = qsz;
83
                ii = qsz;
88
	do	{
84
                do {
89
	  c = *i;
85
                    c = *i;
90
	  *i++ = *j;
86
                    *i++ = *j;
91
	  *j++ = c;
87
                    *j++ = c;
Line 93... Line 89...
93
      }
89
            }
94
    }
90
        }
95
    /*
91
        /*
96
     * Semi-standard quicksort partitioning/swapping
92
         * Semi-standard quicksort partitioning/swapping
97
     */
93
         */
98
    for (i = base, j = max - qsz; ; )
94
        for (i = base, j = max - qsz;;) {
99
    {
-
 
100
      while (i < mid && qcmp(i, mid) <= 0)
95
            while (i < mid && qcmp(i, mid) <= 0)
101
	i += qsz;
96
                i += qsz;
102
      while (j > mid)
97
            while (j > mid) {
103
      {
-
 
104
	if (qcmp(mid, j) <= 0)
98
                if (qcmp(mid, j) <= 0) {
105
	{
-
 
106
	  j -= qsz;
99
                    j -= qsz;
107
	  continue;
100
                    continue;
108
	}
101
                }
109
	tmp = i + qsz;		/* value of i after swap */
102
                tmp = i + qsz; /* value of i after swap */
110
	if (i == mid)
103
                if (i == mid) {
111
	{
-
 
112
	  /* j <-> mid, new mid is j */
104
                    /* j <-> mid, new mid is j */
113
	  mid = jj = j;
105
                    mid = jj = j;
114
	}
-
 
115
	else
106
                } else {
116
	{
-
 
117
	  /* i <-> j */
107
                    /* i <-> j */
118
	  jj = j;
108
                    jj = j;
119
	  j -= qsz;
109
                    j -= qsz;
120
	}
110
                }
121
	goto swap;
111
                goto swap;
122
      }
112
            }
123
      if (i == mid)
113
            if (i == mid) {
124
      {
-
 
125
	break;
114
                break;
126
      }
-
 
127
      else
115
            } else {
128
      {
-
 
129
	/* i <-> mid, new mid is i */
116
                /* i <-> mid, new mid is i */
130
	jj = mid;
117
                jj = mid;
131
	tmp = mid = i;		/* value of i after swap */
118
                tmp = mid = i; /* value of i after swap */
132
	j -= qsz;
119
                j -= qsz;
133
      }
120
            }
Line 147... Line 134...
147
     * correctly, and branching back.  But only repeat
134
         * correctly, and branching back.  But only repeat
148
     * (recursively or by branching) if the partition is
135
         * (recursively or by branching) if the partition is
149
     * of at least size THRESH.
136
         * of at least size THRESH.
150
     */
137
         */
151
    i = (j = mid) + qsz;
138
        i = (j = mid) + qsz;
152
    if ((lo = j - base) <= (hi = max - i))
139
        if ((lo = j - base) <= (hi = max - i)) {
153
    {
-
 
154
      if (lo >= thresh)
140
            if (lo >= thresh)
155
	qst(base, j);
141
                qst(base, j);
156
      base = i;
142
            base = i;
157
      lo = hi;
143
            lo = hi;
158
    }
-
 
159
    else
144
        } else {
160
    {
-
 
161
      if (hi >= thresh)
145
            if (hi >= thresh)
162
	qst(i, max);
146
                qst(i, max);
163
      max = j;
147
            max = j;
164
    }
148
        }
165
  } while (lo >= thresh);
149
    } while (lo >= thresh);
Line 170... Line 154...
170
 * First, set up some global parameters for qst to share.  Then, quicksort
154
 * First, set up some global parameters for qst to share.  Then, quicksort
171
 * with qst(), and then a cleanup insertion sort ourselves.  Sound simple?
155
 * with qst(), and then a cleanup insertion sort ourselves.  Sound simple?
172
 * It's not...
156
 * It's not...
173
 */
157
 */
Line 174... Line -...
174
 
-
 
175
void
158
 
176
qsort(void *base0, size_t n, size_t size, int (*compar)(const void *, const void *))
159
void qsort(void* base0, size_t n, size_t size, int (*compar)(const void*, const void*))
177
{
160
{
178
  char *base = (char *)base0;
161
    char* base = (char*)base0;
179
  char c, *i, *j, *lo, *hi;
162
    char c, *i, *j, *lo, *hi;
Line 184... Line 167...
184
  qsz = size;
167
    qsz = size;
185
  qcmp = compar;
168
    qcmp = compar;
186
  thresh = qsz * THRESH;
169
    thresh = qsz * THRESH;
187
  mthresh = qsz * MTHRESH;
170
    mthresh = qsz * MTHRESH;
188
  max = base + n * qsz;
171
    max = base + n * qsz;
189
  if (n >= THRESH)
172
    if (n >= THRESH) {
190
  {
-
 
191
    qst(base, max);
173
        qst(base, max);
192
    hi = base + thresh;
174
        hi = base + thresh;
193
  }
-
 
194
  else
175
    } else {
195
  {
-
 
196
    hi = max;
176
        hi = max;
197
  }
177
    }
198
  /*
178
    /*
199
   * First put smallest element, which must be in the first THRESH, in
179
     * First put smallest element, which must be in the first THRESH, in
200
   * the first position as a sentinel.  This is done just by searching
180
     * the first position as a sentinel.  This is done just by searching
Line 202... Line 182...
202
   * the min, and swapping it into the first position.
182
     * the min, and swapping it into the first position.
203
   */
183
     */
204
  for (j = lo = base; (lo += qsz) < hi; )
184
    for (j = lo = base; (lo += qsz) < hi;)
205
    if (qcmp(j, lo) > 0)
185
        if (qcmp(j, lo) > 0)
206
      j = lo;
186
            j = lo;
207
  if (j != base)
187
    if (j != base) {
208
  {
-
 
209
    /* swap j into place */
188
        /* swap j into place */
210
    for (i = base, hi = base + qsz; i < hi; )
189
        for (i = base, hi = base + qsz; i < hi;) {
211
    {
-
 
212
      c = *j;
190
            c = *j;
213
      *j++ = *i;
191
            *j++ = *i;
214
      *i++ = c;
192
            *i++ = c;
215
    }
193
        }
216
  }
194
    }
Line 219... Line 197...
219
   * insertion sort.  For each remaining element, min, from [1] to [n-1],
197
     * insertion sort.  For each remaining element, min, from [1] to [n-1],
220
   * set hi to the index of the element AFTER which this one goes.
198
     * set hi to the index of the element AFTER which this one goes.
221
   * Then, do the standard insertion sort shift on a character at a time
199
     * Then, do the standard insertion sort shift on a character at a time
222
   * basis for each element in the frob.
200
     * basis for each element in the frob.
223
   */
201
     */
224
  for (min = base; (hi = min += qsz) < max; )
202
    for (min = base; (hi = min += qsz) < max;) {
225
  {
-
 
226
    while (qcmp(hi -= qsz, min) > 0)
203
        while (qcmp(hi -= qsz, min) > 0)
227
      /* void */;
204
            /* void */;
228
    if ((hi += qsz) != min) {
205
        if ((hi += qsz) != min) {
229
      for (lo = min + qsz; --lo >= min; )
206
            for (lo = min + qsz; --lo >= min;) {
230
      {
-
 
231
	c = *lo;
207
                c = *lo;
232
	for (i = j = lo; (j -= qsz) >= hi; i = j)
208
                for (i = j = lo; (j -= qsz) >= hi; i = j)
233
	  *i = *j;
209
                    *i = *j;
234
	*i = c;
210
                *i = c;
235
      }
211
            }