1 package net.sf.saxon.sort; 2 3 11 12 15 16 17 148 public class GenericSorter extends Object { 149 150 private static final int SMALL = 7; 151 private static final int MEDIUM = 7; 152 private static final int LARGE = 40; 153 154 155 158 protected GenericSorter() {} 159 160 182 public static void quickSort(int fromIndex, int toIndex, Sortable c) { 183 quickSort1(fromIndex, toIndex-fromIndex, c); 184 } 185 186 189 private static void quickSort1(int off, int len, Sortable comp) { 190 if (len < SMALL) { 192 for (int i=off; i<len+off; i++) 193 for (int j=i; j>off && (comp.compare(j-1,j)>0); j--) { 194 comp.swap(j, j-1); 195 } 196 return; 197 } 198 199 int m = off + (len >>> 1); 202 if (len > MEDIUM) { 203 int l = off; 204 int n = off + len - 1; 205 if (len > LARGE) { int s = len >>> 3; l = med3(l, l+s, l+2*s, comp); 208 m = med3(m-s, m, m+s, comp); 209 n = med3(n-2*s, n-s, n, comp); 210 } 211 int c = comp.compare(m,n); 216 m = (comp.compare(l,m)<0 ? 217 (c<0 ? m : comp.compare(l,n)<0 ? n : l) : 218 (c>0 ? m : comp.compare(l,n)>0 ? n : l)); 219 } 220 222 int a = off, b = a, c = off + len - 1, d = c; 224 while (true) { 225 int comparison; 226 while (b <= c && ((comparison=comp.compare(b,m))<=0)) { 227 if (comparison == 0) { 228 if (a==m) m = b; else if (b==m) m = a; comp.swap(a++, b); 231 } 232 b++; 233 } 234 while (c >= b && ((comparison=comp.compare(c,m))>=0)) { 235 if (comparison == 0) { 236 if (c==m) m = d; else if (d==m) m = c; comp.swap(c, d--); 239 } 240 c--; 241 } 242 if (b > c) break; 243 if (b==m) m = d; else if (c==m) m = c; comp.swap(b++, c--); 246 } 247 248 250 int s = Math.min(a-off, b-a ); 251 int aa = off; int bb = b-s; 254 while (--s >= 0) comp.swap(aa++, bb++); 255 int n = off + len; 256 s = Math.min(d-c, n-d-1); 257 aa = b; bb = n-s; 259 while (--s >= 0) comp.swap(aa++, bb++); 260 261 if ((s = b-a) > 1) 263 quickSort1(off, s, comp); 264 if ((s = d-c) > 1) 265 quickSort1(n-s, s, comp); 266 } 267 268 271 private static int med3(int a, int b, int c, Sortable comp) { 272 int bc = comp.compare(b,c); 273 return (comp.compare(a,b)<0 ? 274 (bc<0 ? b : comp.compare(a,c)<0 ? c : a) : 275 (bc>0 ? b : comp.compare(a,c)>0 ? c : a)); 276 } 277 278 279 286 309 public static void mergeSort(int fromIndex, int toIndex, Sortable c) { 310 322 323 324 if (toIndex - fromIndex < SMALL) { 326 for (int i = fromIndex; i < toIndex; i++) { 327 for (int j = i; j > fromIndex && (c.compare(j - 1, j) > 0); j--) { 328 c.swap(j, j - 1); 329 } 330 } 331 return; 332 } 333 334 int mid = (fromIndex + toIndex) >>> 1; mergeSort(fromIndex, mid, c); 337 mergeSort(mid, toIndex, c); 338 339 if (c.compare(mid - 1, mid) <= 0) return; 342 343 inplaceMerge(fromIndex, mid, toIndex, c); 345 } 346 347 355 private static void inplaceMerge(int first, int middle, int last, Sortable comp) { 356 if (first >= middle || middle >= last) 357 return; 358 if (last - first == 2) { 359 if (comp.compare(middle, first)<0) { 360 comp.swap(first,middle); 361 } 362 return; 363 } 364 int firstCut; 365 int secondCut; 366 if (middle - first > last - middle) { 367 firstCut = first + ((middle - first) >>> 1); int _first = middle; 371 int len = last - _first; 372 while (len > 0) { 373 int half = len >>> 1; int mid = _first + half; 375 if (comp.compare(mid, firstCut)<0) { 376 _first = mid + 1; 377 len -= half + 1; 378 } 379 else { 380 len = half; 381 } 382 } 383 secondCut = _first; 384 } 385 else { 386 secondCut = middle + ((last - middle) >>> 1); int _first = first; 390 int len = middle - _first; 391 while (len > 0) { 392 int half = len >>> 1; int mid = _first + half; 394 if (comp.compare(secondCut, mid)<0) { 395 len = half; 396 } 397 else { 398 _first = mid + 1; 399 len -= half + 1; 400 } 401 } 402 firstCut = _first; 403 } 404 405 int first2 = firstCut; int middle2 = middle; int last2 = secondCut; 412 if (middle2 != first2 && middle2 != last2) { 413 int first1 = first2; int last1 = middle2; 414 while (first1 < --last1) comp.swap(first1++,last1); 415 first1 = middle2; last1 = last2; 416 while (first1 < --last1) comp.swap(first1++,last1); 417 first1 = first2; last1 = last2; 418 while (first1 < --last1) comp.swap(first1++,last1); 419 } 420 422 middle = firstCut + (secondCut - middle); 423 inplaceMerge(first, firstCut, middle, comp); 424 inplaceMerge(middle, secondCut, last, comp); 425 } 426 427 493 } 494 | Popular Tags |