Advertisement
chavit

Untitled

Jun 6th, 2011
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.21 KB | None | 0 0
  1. import java.io.IOException;
  2. import java.util.Arrays;
  3. import java.util.Random;
  4.  
  5. public class Main {
  6.  
  7.  
  8.     // сляние двух групп елементов одинокового размера
  9.     void mergegroup(int a[], int n, int st1, int st2, int st3) {
  10.       swapgroup(a, n, st1, st3);
  11.                 int take1 = 0;
  12.                 int take2 = 0;
  13.                 for (int i = 0; i < 2 * n; i++) {
  14.                         if ((take2 == n)
  15.                                         || ((take1 < n) && (a[take1 + st3] < a[take2 + st2]))) {
  16.                                 int t = a[st1 + i];
  17.                                 a[st1 + i] = a[take1 + st3];
  18.                                 a[take1 + st3] = t;
  19.                                 take1++;
  20.                         } else {
  21.                                 int t = a[st1 + i];
  22.                                 a[st1 + i] = a[take2 + st2];
  23.                                 a[take2 + st2] = t;
  24.                                 take2++;
  25.                         }
  26.                 }
  27.         }
  28.  
  29.  
  30.         // сортировка выбором
  31.         void slowsort(int a[], int st, int en) {
  32.                 for (int i = st; i < en; i++)
  33.                         for (int j = i + 1; j < en; j++) {
  34.                                 if (a[i] > a[j]) {
  35.                                         int k = a[i];
  36.                                         a[i] = a[j];
  37.                                         a[j] = k;
  38.                                 }
  39.                         }
  40.         }
  41.  
  42.  
  43.         // обмен местами двух групп елементов одинакового размера    
  44.         void swapgroup(int a[], int n, int st1, int st2) {
  45.                 for (int i = 0; i < n; i++) {
  46.                         int k = a[st1 + i];
  47.                         a[st1 + i] = a[st2 + i];
  48.                         a[st2 + i] = k;
  49.                 }
  50.         }
  51.  
  52.  
  53.         //слияние
  54.         void merge(int[] a, int n) {
  55.                 if (n <= 16) {
  56.                         slowsort(a, 0, n);
  57.                         return;
  58.                 }
  59.                
  60.                 // разрез на группы длиной корень из n
  61.                 int sizegroup = (int) Math.sqrt(n);
  62.                 int remainder = n % sizegroup;
  63.                 int numofgrp = n / sizegroup - 1;
  64.                
  65.                 // поиск конца первого массива
  66.                 int posgap = 0;
  67.                 while ((posgap < sizegroup * numofgrp) && (a[posgap] <= a[posgap + 1]))
  68.                         posgap++;
  69.                        
  70.                 // обмен группы содержащей конец первого массива  с последней и обьединение с остатком
  71.                 swapgroup(a, sizegroup, numofgrp * sizegroup, posgap - posgap
  72.                                 % sizegroup);
  73.                 remainder += sizegroup;
  74.                
  75.                 // сортировка групп по первому елементу(в случае равенства по последнему)
  76.                 for (int i = 0; i < numofgrp - 1; i++) {
  77.                         int minnum = i;
  78.                         for (int j = i + 1; j < numofgrp; j++)
  79.                                 if ((a[j * sizegroup] < a[minnum * sizegroup])
  80.                                         || ((a[j * sizegroup] == a[minnum * sizegroup])
  81.                                         && (a[(j + 1) * sizegroup - 1] < a[(minnum + 1) *sizegroup-1])))
  82.                                       minnum = j;
  83.                         swapgroup(a, sizegroup, i * sizegroup, minnum * sizegroup);
  84.                 }
  85.                
  86.                 // поочередное слияние групп
  87.                 for (int i = 0; i < numofgrp - 1; i++) {
  88.                         mergegroup(a, sizegroup, i * sizegroup, (i + 1) * sizegroup,
  89.                                         numofgrp * sizegroup);
  90.                 }
  91.                
  92.                 // сортировка конца массива
  93.                 slowsort(a, n - 2 * remainder, n);
  94.                
  95.                 // поочередное слияние групп в обратную сторону
  96.                 for (int i = n - 2 * remainder; i >= remainder; i -= remainder)
  97.                         mergegroup(a, remainder, i - remainder, i, n - remainder);
  98.                        
  99.                 // сортировка начала и конца массива
  100.                 slowsort(a, 0, 2 * remainder);
  101.                 slowsort(a, n - remainder, n);
  102.         }
  103.  
  104.         // сортировка
  105.         void sort(int[] a) {
  106.                 int n = a.length;
  107.                 for (int stp2 = 1; stp2 <= n; stp2 *= 2)
  108.                         for (int i = 0; i < n; i += stp2) {
  109.                                 int size = Math.min(n, i + stp2) - i;  
  110.                                 swapgroup(a, size, 0, i);      // для удобства реализации перемещаем  
  111.                                 merge(a, size);                // требуемый кусок масcива в начало
  112.                                 swapgroup(a, size, 0, i);      // там его сортируем и возвращаем обратно
  113.                         }
  114.                 if (n > 16)
  115.                         merge(a, n);
  116.  
  117.         }
  118.  
  119.  
  120.         void testsort() throws IOException {
  121.                 int n = 100000;
  122.                 int[] a = new int[n];
  123.                 Random st = new Random();
  124.                 for (int i = 0; i < n; i++)
  125.                         a[i] = st.nextInt();
  126.                 int[] b = a.clone();
  127.                 Arrays.sort(b);
  128.                 sort(a);
  129.                 for (int i = 0; i < n; i++)
  130.                         if (a[i] != b[i])
  131.                                 throw new AssertionError();
  132.         };
  133.  
  134.  
  135.         void run() throws IOException {
  136.                 for (int i = 0; i < 10; i++) {
  137.                         testsort();
  138.                 }
  139.         }
  140.  
  141.  
  142.         public static void main(String[] args) throws IOException {
  143.                 new Main().run();
  144.         }
  145. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement