Advertisement
Guest User

Untitled

a guest
Nov 27th, 2014
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.43 KB | None | 0 0
  1. // Мазырин
  2. // Роман
  3.  
  4. /*
  5. 7_1. Быстрейшая сортировка.
  6. Дан массив целых чисел в диапазоне [0..10^9]. Размер массива кратен 10 и ограничен сверху значением 2.5 * 10^7 элементов. Все значения массива являются элементами псевдо-рандомной последовательности. Необходимо отсортировать элементы массива за минимально время и вывести каждый десятый элемент отсортированной последовательности.
  7. Минимальный набор оптимизаций, который необходимо реализовать:
  8. 1. Оптимизация ввода/вывода
  9. 2. Оптимизация выбора опорного элемента
  10. 3. Оптимизация Partition
  11. 4. Оптимизация рекурсии
  12. 5. Оптимизация концевой рекурсии
  13.  */
  14.  
  15. #include <iostream>
  16. #include <assert.h>
  17. #include <cstdio>
  18.  
  19. //#define DBG
  20.  
  21. #ifdef DBG
  22. #include <time.h>
  23. #endif
  24.  
  25. using namespace std;
  26.  
  27. const int INSERTION_SORT_SIZE = 20;
  28.  
  29. struct Boundary {
  30.     int left;
  31.     int right;
  32.     Boundary() : left(0), right(0) {};
  33.     Boundary(int pLeft, int pRight) {
  34.         left = pLeft;
  35.         right = pRight;
  36.     }
  37.     Boundary(const Boundary& b) {
  38.         left = b.left;
  39.         right = b.right;
  40.     }
  41. };
  42.  
  43. class Stack {
  44. private:
  45.     Boundary* arr;
  46.     int size;
  47.     int tail;
  48. public:
  49.     Stack() : arr(0), tail(0), size(0) {};
  50.     Stack(int beginSize) {
  51.         tail = 0;
  52.         size = beginSize;
  53.         arr = new Boundary[beginSize]();
  54.     }
  55.  
  56.     int getCount() {
  57.         return tail;
  58.     }
  59.  
  60.     void grow() {
  61.         int newSize = size*2;
  62.         Boundary* tempArr = new Boundary[newSize]();
  63.         for( int i = 0; i < size; i++ ) {
  64.             tempArr[i] = arr[i];
  65.         }
  66.         size = newSize;
  67.         delete [] arr;
  68.         arr = tempArr;
  69.     }
  70.  
  71.     void push(Boundary b) {
  72.         if( tail == size ) {
  73.             grow();
  74.         }
  75.         arr[tail++] = b;
  76.     }
  77.  
  78.     Boundary pop() {
  79.         assert(tail > 0);
  80.         return arr[--tail];
  81.     }
  82.  
  83.     ~Stack() {
  84.         delete [] arr;
  85.     }
  86.  
  87. };
  88.  
  89. int findMedianIndex(int* arr, int left, int right) {
  90.     int middleElemKey = (left+right)/2;
  91.     if( (arr[left] >= arr[right] && arr[left] <= arr[middleElemKey]) ||
  92.             (arr[left] >= arr[middleElemKey] && arr[left] <= arr[right]) ) {
  93.         return left;
  94.     } else {
  95.         if( arr[middleElemKey] >= arr[right] ) {
  96.             return right;
  97.         } else {
  98.             return middleElemKey;
  99.         }
  100.     }
  101. }
  102.  
  103. void insertionSort(int* arr, int left, int right) {
  104.     for(int i = left+1; i <= right; i++ ) {
  105.         for( int j = i-1; (j >= left) && (arr[j] > arr[j+1]); j--) {
  106.             swap(arr[j], arr[j+1]);
  107.         }
  108.     }
  109. }
  110.  
  111. int partition(int* arr, int left, int right, int pivotPos) {
  112.     swap(arr[right], arr[pivotPos]);
  113.     int i = left;
  114.     int j = left;
  115.     while( j < right ) {
  116.         if( arr[j] >= arr[right] ) {
  117.             j++;
  118.         } else {
  119.             if( j != i ) {
  120.                 swap(arr[j], arr[i]);
  121.             }
  122.             i++;
  123.             j++;
  124.         }
  125.     }
  126.     swap(arr[i], arr[right]);
  127.     return i;
  128. }
  129.  
  130. void SuperQuickSort(int* arr, int size) {
  131.  
  132.     Stack intervals(1000);
  133.     int left = 0;
  134.     int right = size - 1;
  135.     int pivot = 0;
  136.     do {
  137.         // Сортируем левые интервалы до тех пор, пока не дойдем до сортировки вставками, а правые пихаем в стек
  138.         do {
  139.             if( right - left <= INSERTION_SORT_SIZE ) {
  140.                 insertionSort(arr, left, right);
  141.                 break;
  142.             }
  143.             pivot = findMedianIndex(arr, left, right);
  144.             pivot = partition(arr, left, right, pivot);
  145.             intervals.push(Boundary(pivot+1, right));
  146.             right = pivot;
  147.         } while( true );
  148.  
  149.         // Начинаем сортировать правые стороны до тех пор, пока интервал не станет больше INSERTION_SORT_SIZE
  150.         while( (right - left <= INSERTION_SORT_SIZE) && (right != size-1) ) {
  151.             Boundary a = intervals.pop();
  152.             left = a.left;
  153.             right = a.right;
  154.             if( right - left <= INSERTION_SORT_SIZE ) {
  155.                 insertionSort(arr, left, right);
  156.             }
  157.         }
  158.         // До тех пор, пока есть интервалы в стеке или текущий интервал больше чем INSERTION_SORT_SIZE
  159.     } while( intervals.getCount() > 0 || right-left > INSERTION_SORT_SIZE );
  160. }
  161.  
  162. int main() {
  163.  
  164.     ios_base::sync_with_stdio(false);
  165.  
  166.     int* arr = new int[25000000];
  167.  
  168.     register int size = 0;
  169.     while( scanf("%d", &arr[size]) == 1) {
  170.         size++;
  171.     }
  172.  
  173.     #ifdef DBG
  174.     clock_t start = clock();
  175.  
  176.     SuperQuickSort(arr, size);
  177.     for( int i = 9; i < size; i += 10 ) {
  178.         printf("%d ", arr[i]);
  179.     }
  180.  
  181.     printf("\n%f", (float)(clock()-start)/CLOCKS_PER_SEC);
  182.     #endif
  183.  
  184.     #ifndef DBG
  185.     SuperQuickSort(arr, size);
  186.     for( int i = 9; i < size; i += 10 ) {
  187.         printf("%d ", arr[i]);
  188.     }
  189.     #endif
  190.  
  191.     delete [] arr;
  192.     return 0;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement