MythTV master
quickselect.h
Go to the documentation of this file.
1#ifndef QUICKSELECT_H
2#define QUICKSELECT_H
3
4template <typename T>
5void ELEM_SWAP(T& a, T& b)
6{
7 T t = a;
8 a = b;
9 b = t;
10}
11
12template <typename T>
13T quick_select(T *arr, int nelems, int select)
14{
15 int low = 0;
16 int high = nelems - 1;
17
18 for (;;) {
19 if (high <= low) /* One element only */
20 return arr[select];
21
22 if (high == low + 1) { /* Two elements only */
23 if (arr[low] > arr[high])
24 ELEM_SWAP<T>(arr[low], arr[high]);
25 return arr[select];
26 }
27
28 /* Find median of low, middle and high items; swap into position low */
29 int middle = (low + high) / 2;
30 if (arr[middle] > arr[high]) ELEM_SWAP<T>(arr[middle], arr[high]);
31 if (arr[low] > arr[high]) ELEM_SWAP<T>(arr[low], arr[high]);
32 if (arr[middle] > arr[low]) ELEM_SWAP<T>(arr[middle], arr[low]);
33
34 /* Swap low item (now in position middle) into position (low+1) */
35 ELEM_SWAP<T>(arr[middle], arr[low+1]);
36
37 /* Nibble from each end towards middle, swapping items when stuck */
38 int ll = low + 1;
39 int hh = high;
40 while (hh >= ll) {
41 ll++;
42 while (arr[low] > arr[ll])
43 ll++;
44
45 hh--;
46 while (arr[hh] > arr[low])
47 hh--;
48
49 if (hh < ll)
50 break;
51
52 ELEM_SWAP<T>(arr[ll], arr[hh]);
53 }
54
55 /* Swap middle item (in position low) back into correct position */
56 ELEM_SWAP<T>(arr[low], arr[hh]);
57
58 /* Re-set active partition */
59 if (hh <= select)
60 low = ll;
61 if (hh >= select)
62 high = hh - 1;
63 }
64}
65
66template <typename T>
67T quick_select_median(T *arr, int nelems)
68{
69 return quick_select<T>(arr, nelems, (nelems - 1) / 2);
70}
71
72#endif /* !QUICKSELECT_H */
T quick_select_median(T *arr, int nelems)
Definition: quickselect.h:67
void ELEM_SWAP(T &a, T &b)
Definition: quickselect.h:5
T quick_select(T *arr, int nelems, int select)
Definition: quickselect.h:13