Partitioning
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | void Bentley_McIlroy(int*& lo, int*& hi) { using std::swap; int pivot = *lo; int *j = lo, *i = hi--, *p = lo + 1, *q = hi; while (true) { while (pivot < *(--i)); while (*(++j) < pivot) if (j == hi) break; if (j >= i) break; swap(*i, *j); if (*i == pivot) swap(*q--, *i); if (*j == pivot) swap(*p++, *j); } int min = std::min(p - lo, i - p + 1); for (int f = 0; f < min; ++f) swap(*(lo + f), *(i - f)); int min2 = std::min(hi - q, q - i); for (int f = 1; f < min2; ++f) swap(*(hi - f), *(i + f)); lo = ++i - (p - lo); hi = i + (hi - q); } int* lomutoPartition(int* p, int* r) { using std::swap; int pivot = *(--r), *i = p - 1; for (int* j = p; j != r; ++j) { if (*j <= pivot) swap( *(++i), *j); } swap(*r, *(++i)); return i; } int* hoare(int *lo, int *hi) { using std::swap; int pivot = *lo, *i = lo, *j = hi--; while (true) { while (*(++i) < pivot) if (i == hi) break; while (pivot < *(--j) ); if (j <= i) break; swap(*i, *j); } swap(*j, *lo); return j; } void dijkstra_3_way_partitioning(int*& l, int*& g) { using std::swap; int *i = l + 1, pivot = *l; while (i < g) { if (*i < pivot) swap(*i++, *l++); else if (*i > pivot) swap(*i, *(--g)); else i++; } } void dual_pivot_partitioning(int*& L, int*& G) { using std::swap; if (*L > *(--G)) swap( *L, *G); int pivot1 = *L, *first = L, *last = G, pivot2 = *G--, *K = L++; while (K <= G) { if (*K < pivot1) swap(*L++, *K++); else if (*K > pivot2) swap(*G--, *K); else ++K; } swap(*(--L), *first); swap(*(++G), *last); } |
Pivot and shuffle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | std::random_device rd; std::mt19937 mt(rd()); int* random(int *ini, int *fin) { std::uniform_int_distribution <> dist(0, fin - ini - 1); return ini + dist(mt); } int* randomMedianOfN(int * ini, int * fin, int N) { if (fin - ini < N) return ini; for (int * i = ini; i != ini + N; ++i) { int * r = Pivots::random(i, fin); std::swap(*i, *r); } std::nth_element(ini, ini + N / 2, ini + N); return ini + 1; } void fisher_yates_shuffle(int *ini, int *fin) { for (auto i = ini; ini != fin; ++ini) std::swap(*Pivots::random(ini, fin), *ini); } |
Quicksort
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | void B_M_sort(int* ini, int* fin) { if (ini >= fin - 1) return; auto ini2 = ini, fin2 = fin; Particions::Bentley_McIlroy(ini2, fin2); B_M_sort(ini, ini2); B_M_sort(fin2, fin); } void sort(int* ini, int *fin) { if (ini >= fin - 1) return; auto pivot = Particions::hoare(ini, fin); sort(ini, pivot); sort(pivot + 1, fin); } void Lomutosort(int* ini, int *fin) { if (ini >= fin - 1) return; auto pivot = Particions::lomutoPartition(ini, fin); sort(ini, pivot); sort(pivot + 1, fin); } void javaSort(int* ini, int *fin) { if (ini >= fin - 1) return; auto ini2 = ini, fin2 = fin; Particions::dual_pivot_partitioning(ini2, fin2); javaSort(ini, ini2); if(*ini2 != *fin2) javaSort(ini2 + 1, fin2); javaSort(fin2 + 1, fin); } void iterativeSort(int* ini, int* fin) { unsigned MaxLength = 2 * static_cast<unsigned> (std::log2l(fin - ini)); Stack<int*> stack(MaxLength); stack.push(nullptr); stack.push(nullptr); while (!stack.empty()) { while (ini < fin - 1) { auto ini2 = ini, fin2 = fin; Particions::Bentley_McIlroy(ini2, fin2); if ((ini2 - ini) >(fin - fin2)) { stack.push(ini2); stack.push(ini); ini = fin2; } else { stack.push(fin); stack.push(fin2); fin = ini2; } } ini = stack.pop(); fin = stack.pop(); } } |
No comments:
Post a Comment