Advertisement
Guest User

Untitled

a guest
May 26th, 2016
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.55 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Runtime.CompilerServices;
  7.  
  8. namespace ArrayAlgorithms
  9. {
  10. public class Sort
  11. {
  12. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  13. private static void Swap<T>(T[] array, int key1, int key2)
  14. {
  15. T tmp = array[key1];
  16. array[key1] = array[key2];
  17. array[key2] = tmp;
  18. //Swap(ref array[key1], ref array[key2]);
  19. }
  20.  
  21. private static void HeapSort<T>(T[] array, int left, int right, IComparer<T> comparer)
  22. {
  23. int i;
  24. //Поднимаем выше элементы с большими значениями
  25. //В корне - макс. элемент
  26. for (i = left + (right - left) / 2; i >= left; --i)
  27. SiftDown(array, i, right, comparer);
  28.  
  29. //Вытаскиваем максимум, помещаем в конец,
  30. //сокращаем правую границу на 1 и просеиваем кучу
  31. for (i = right; i > left; --i)
  32. {
  33. Swap(array, 0, i);
  34. SiftDown(array, 0, i - 1, comparer);
  35. }
  36. }
  37.  
  38. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  39. private static void SiftDown<T>(T[] array, int itemIndex, int right, IComparer<T> comparer)
  40. {
  41. while (itemIndex * 2 + 1 <= right)
  42. {
  43. int maxChild;
  44. if (itemIndex * 2 + 1 >= right || comparer.Compare(array[itemIndex * 2 + 1], array[itemIndex * 2 + 2]) > 0)// array[itemIndex * 2 + 1] > array[itemIndex * 2 + 2])
  45. maxChild = itemIndex * 2 + 1;
  46. else
  47. maxChild = itemIndex * 2 + 2;
  48.  
  49. if (comparer.Compare(array[itemIndex], array[maxChild]) < 0)// array[itemIndex] < array[maxChild])
  50. {
  51. Swap(array, itemIndex, maxChild);
  52. itemIndex = maxChild;
  53. }
  54. else break;
  55. }
  56. }
  57.  
  58. private static int Partition<T>(T[] input, int left, int right, IComparer<T> comparer)
  59. {
  60. //int index = left + (right - left) / 2;
  61. //SwapIfGreater(input, Comparer<int>.Default, left, index);
  62. //SwapIfGreater(input, Comparer<int>.Default, left, right);
  63. //SwapIfGreater(input, Comparer<int>.Default, index, right);
  64.  
  65. //int pivot = input[index];
  66. //Swap(input, index, right);
  67. //int i = left, j = right - 1;
  68.  
  69. //for(;i< j;)
  70. //{
  71. // do { }
  72. // while (i<right-1&&input[i++] < pivot) ;
  73. // do
  74. // {
  75. // }
  76.  
  77. // while (j>=left&&input[j--] >= pivot) ;
  78. // if (i < j)
  79. // Swap(input, i, j);
  80. // else break;
  81. //}
  82. //if(i<right)
  83. // Swap(input, i, right);
  84. //return i;
  85.  
  86. var index = left + (right - left) / 2;
  87. SwapIfGreater(input, comparer, left, right);
  88. SwapIfGreater(input, comparer, left, index);
  89. SwapIfGreater(input, comparer, right, index);
  90. //В последний элемент блока записываем медиану первого, среднего и последнего
  91. var pivot = input[right];
  92.  
  93. var i = left;
  94. for (var j = left; j < right; ++j)
  95. {
  96. if (comparer.Compare(input[j], pivot) <= 0)// <= pivot)
  97. Swap(input, i++, j);
  98. }
  99.  
  100. input[right] = input[i];
  101. input[i] = pivot;
  102.  
  103. return i;
  104. }
  105.  
  106. public static int IsSorted(int[] array)
  107. {
  108. for (var i = 0; i < array.Length - 1; ++i)
  109. if (array[i] > array[i + 1])
  110. return i;
  111. return -1;
  112. }
  113.  
  114. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  115. private static void SwapIfGreater<T>(T[] array, IComparer<T> comparer, int key1, int key2)
  116. {
  117. if (comparer.Compare(array[key1], array[key2]) > 0)
  118. Swap(array, key1, key2);
  119. //Swap(ref array[key1], ref array[key2]);
  120. }
  121.  
  122. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  123. public static void InsertionSort<T>(T[] array, int l, int r, IComparer<T> comparer)
  124. {
  125. for (var i = l + 1; i <= r; ++i)
  126. {
  127. int j;
  128. var key = array[i];
  129. for (j = i; j > l && comparer.Compare(array[j - 1], key) > 0; --j)
  130. array[j] = array[j - 1];
  131. array[j] = key;
  132. }
  133. }
  134.  
  135.  
  136. private static void QuickSort<T>(T[] input, int left, int right, IComparer<T> comparer, int depth = 32)
  137. {
  138. while (true)
  139. {
  140. var length = right - left + 1;
  141. if (length <= 16)
  142. {
  143. switch (length)
  144. {
  145. case 1:
  146. break;
  147. case 2:
  148. SwapIfGreater(input, comparer, left, right);
  149. break;
  150. case 3:
  151. SwapIfGreater(input, comparer, left, right - 1);
  152. SwapIfGreater(input, comparer, left, right);
  153. SwapIfGreater(input, comparer, right - 1, right);
  154. break;
  155. default:
  156. InsertionSort(input, left, right, comparer);
  157. break;
  158. }
  159. }
  160. else if (depth == 0)
  161. {
  162. HeapSort(input, left, right, comparer);
  163. }
  164. else
  165. {
  166. --depth;
  167. var q = Partition(input, left, right, comparer);
  168. QuickSort(input, left, q - 1, comparer, depth);
  169. left = q + 1;
  170. continue;
  171. }
  172. break;
  173. }
  174. }
  175.  
  176. public static void QuickSort<T>(T[] array, IComparer<T> comparer)
  177. {
  178. QuickSort(array, 0, array.Length - 1, Comparer<T>.Default);
  179. }
  180.  
  181.  
  182.  
  183. private static void HeapSort<T>(T[] array, int left, int right) where T :IComparable<T>
  184. {
  185. int i;
  186. //Поднимаем выше элементы с большими значениями
  187. //В корне - макс. элемент
  188. for (i = left + (right - left) / 2; i >= left; --i)
  189. SiftDown(array, i, right);
  190.  
  191. //Вытаскиваем максимум, помещаем в конец,
  192. //сокращаем правую границу на 1 и просеиваем кучу
  193. for (i = right; i > left; --i)
  194. {
  195. Swap(array, 0, i);
  196. SiftDown(array, 0, i - 1);
  197. }
  198. }
  199. //[MethodImpl(MethodImplOptions.AggressiveInlining)]
  200. private static void SiftDown<T>(T[] array, int itemIndex, int right) where T :IComparable<T>
  201. {
  202. while (itemIndex * 2 + 1 <= right)
  203. {
  204. int maxChild;
  205. if (itemIndex * 2 + 1 >= right || array[itemIndex * 2 + 1].CompareTo(array[itemIndex * 2 + 2]) > 0)// array[itemIndex * 2 + 1] > array[itemIndex * 2 + 2])
  206. maxChild = itemIndex * 2 + 1;
  207. else
  208. maxChild = itemIndex * 2 + 2;
  209.  
  210. if (array[itemIndex].CompareTo(array[maxChild]) < 0)// array[itemIndex] < array[maxChild])
  211. {
  212. Swap(array, itemIndex, maxChild);
  213. itemIndex = maxChild;
  214. }
  215. else break;
  216. }
  217. }
  218.  
  219. private static int Partition<T>(T[] input, int left, int right) where T :IComparable<T>
  220. {
  221. //int index = left + (right - left) / 2;
  222. //SwapIfGreater(input, Comparer<int>.Default, left, index);
  223. //SwapIfGreater(input, Comparer<int>.Default, left, right);
  224. //SwapIfGreater(input, Comparer<int>.Default, index, right);
  225.  
  226. //int pivot = input[index];
  227. //Swap(input, index, right);
  228. //int i = left, j = right - 1;
  229.  
  230. //for(;i< j;)
  231. //{
  232. // do { }
  233. // while (i<right-1&&input[i++] < pivot) ;
  234. // do
  235. // {
  236. // }
  237.  
  238. // while (j>=left&&input[j--] >= pivot) ;
  239. // if (i < j)
  240. // Swap(input, i, j);
  241. // else break;
  242. //}
  243. //if(i<right)
  244. // Swap(input, i, right);
  245. //return i;
  246.  
  247. var index = left + (right - left) / 2;
  248. SwapIfGreater(input, left, right);
  249. SwapIfGreater(input, left, index);
  250. SwapIfGreater(input, right, index);
  251. //В последний элемент блока записываем медиану первого, среднего и последнего
  252. var pivot = input[right];
  253.  
  254. var i = left;
  255. for (var j = left; j < right; ++j)
  256. {
  257. if (input[j].CompareTo( pivot) <= 0)// <= pivot)
  258. Swap(input, i++, j);
  259. }
  260.  
  261. input[right] = input[i];
  262. input[i] = pivot;
  263.  
  264. return i;
  265. }
  266.  
  267.  
  268.  
  269. public static void TestSort(Action<int[]> sort, int size)
  270. {
  271. var array = new int[size];
  272. var rnd = new Random();
  273. for (var i = 0; i < size; ++i)
  274. array[i] = rnd.Next();
  275. var sw = new System.Diagnostics.Stopwatch();
  276.  
  277. sw.Start();
  278. sort(array);
  279. sw.Stop();
  280.  
  281. if (IsSorted(array) > 0)
  282. Console.WriteLine("Sorting failed!");
  283. Console.WriteLine("Random test " + size + " " + sort.Method + ": " + sw.ElapsedMilliseconds);
  284.  
  285. for (var i = 0; i < size; ++i)
  286. array[i] = i + rnd.Next(50) * (rnd.Next(2) > 0 ? -1 : 1);
  287. sw.Restart();
  288. sort(array);
  289. sw.Stop();
  290. Console.WriteLine("Nearly sorted test " + size + " " + sort.Method + ": " + sw.ElapsedMilliseconds);
  291.  
  292. for (var i = 0; i < size; ++i)
  293. array[i] = size - i;
  294. sw.Restart();
  295. sort(array);
  296. sw.Stop();
  297. Console.WriteLine("Reversed test " + size + " " + sort.Method + ": " + sw.ElapsedMilliseconds);
  298.  
  299.  
  300. var values = new int[100];
  301. for (int i = 0; i < 100; i++)
  302. values[i] = rnd.Next();
  303.  
  304. for (var i = 0; i < size; ++i)
  305. array[i] = values[rnd.Next(100)];//rnd.Next((int)Math.Sqrt(size)/10);
  306.  
  307. sw.Restart();
  308. sort(array);
  309. sw.Stop();
  310. Console.WriteLine("Few unique test " + size + " " + sort.Method + ": " + sw.ElapsedMilliseconds);
  311.  
  312. }
  313.  
  314. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  315. private static void SwapIfGreater<T>(T[] array, int key1, int key2)where T :IComparable<T>
  316. {
  317. if (array[key1].CompareTo(array[key2]) > 0)
  318. Swap(array, key1, key2);
  319. //Swap(ref array[key1], ref array[key2]);
  320. }
  321.  
  322. //[MethodImpl(MethodImplOptions.AggressiveInlining)]
  323. public static void InsertionSort<T>(T[] array, int l, int r)where T :IComparable<T>
  324. {
  325. for (var i = l + 1; i <= r; ++i)
  326. {
  327. int j;
  328. var key = array[i];
  329. for (j = i; j > l && array[j - 1].CompareTo(key) > 0; --j)
  330. array[j] = array[j - 1];
  331. array[j] = key;
  332. }
  333. }
  334.  
  335.  
  336. private static void QuickSort<T>(T[] input, int left, int right, int depth = 32)where T :IComparable<T>
  337. {
  338. while (true)
  339. {
  340. var length = right - left + 1;
  341. if (length <= 16)
  342. {
  343. switch (length)
  344. {
  345. case 1:
  346. break;
  347. case 2:
  348. SwapIfGreater(input, left, right);
  349. break;
  350. case 3:
  351. SwapIfGreater(input, left, right - 1);
  352. SwapIfGreater(input, left, right);
  353. SwapIfGreater(input, right - 1, right);
  354. break;
  355. default:
  356. InsertionSort(input, left, right);
  357. break;
  358. }
  359. }
  360. else if (depth == 0)
  361. {
  362. HeapSort(input, left, right);
  363. }
  364. else
  365. {
  366. --depth;
  367. var q = Partition(input, left, right);
  368. QuickSort(input, left, q - 1, depth);
  369. left = q + 1;
  370. continue;
  371. }
  372. break;
  373. }
  374. }
  375.  
  376. public static void QuickSort<T>(T[] array) where T :IComparable<T>
  377. {
  378.  
  379. //if(typeof(T).IsPrimitive)
  380. //{
  381.  
  382. // //NativeMethods.CppSort.CppQuickSort(array, 0, array.Length - 1);
  383. //}
  384. //else
  385. QuickSort(array, 0, array.Length - 1);// Comparer<T>.Default);
  386.  
  387. }
  388.  
  389.  
  390.  
  391. }
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement