|
| 1 | +using System; |
| 2 | +using System.Diagnostics; |
| 3 | + |
| 4 | +namespace Cabana |
| 5 | +{ |
| 6 | + using static System.Console; |
| 7 | + /* |
| 8 | + * Bubble Sort |
| 9 | + * Credit : http://www.c-sharpcorner.com/UploadFile/3d39b4/bubble-sort-in-C-Sharp/ |
| 10 | + * : http://stackoverflow.com/questions/14768010/simple-bubble-sort-c-sharp |
| 11 | + */ |
| 12 | + public class ArraySorting |
| 13 | + { |
| 14 | + public ArraySorting() |
| 15 | + { |
| 16 | + Stopwatch watch = new Stopwatch(); |
| 17 | + double elapsedTime; // time in second, accurate to about millseconds |
| 18 | + |
| 19 | + |
| 20 | + Write(new string('-', 25)); |
| 21 | + Write("Sort [Bubble sort]"); |
| 22 | + Write(new string('-', 25)); |
| 23 | + WriteLine(); |
| 24 | + int[] arr = new int[10000]; |
| 25 | + ArraySorting.IntArrayGenerate(arr, 12); |
| 26 | + watch.Start(); |
| 27 | + ArraySorting.BubbleSort(arr); |
| 28 | + |
| 29 | + watch.Stop(); |
| 30 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 31 | + WriteLine(new string(' ', 10) + "Bubble Sort: {0:F3}", elapsedTime); |
| 32 | + WriteLine(); |
| 33 | + |
| 34 | + watch.Reset(); |
| 35 | + Write(new string('-', 25)); |
| 36 | + Write("Sort [Selection sort]"); |
| 37 | + Write(new string('-', 25)); |
| 38 | + WriteLine(); |
| 39 | + int[] arr2 = new int[10000]; |
| 40 | + ArraySorting.IntArrayGenerate(arr2, 12); |
| 41 | + watch.Start(); |
| 42 | + ArraySorting.IntArraySelectionSort(arr2); |
| 43 | + watch.Stop(); |
| 44 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 45 | + WriteLine(new string(' ', 10) + "Selection Sort: {0:F3}", elapsedTime); |
| 46 | + WriteLine(); |
| 47 | + |
| 48 | + watch.Reset(); |
| 49 | + Write(new string('-', 25)); |
| 50 | + Write("Sort [Insertion sort]"); |
| 51 | + Write(new string('-', 25)); |
| 52 | + WriteLine(); |
| 53 | + int[] arr3 = new int[10000]; |
| 54 | + ArraySorting.IntArrayGenerate(arr3, 12); |
| 55 | + watch.Start(); |
| 56 | + ArraySorting.IntArrayInsertionSort(arr3); |
| 57 | + watch.Stop(); |
| 58 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 59 | + WriteLine(new string(' ', 10) + "Insertion Sort: {0:F3}", elapsedTime); |
| 60 | + WriteLine(); |
| 61 | + |
| 62 | + watch.Reset(); |
| 63 | + Write(new string('-', 25)); |
| 64 | + Write("Sort [Shell sort]"); |
| 65 | + Write(new string('-', 25)); |
| 66 | + WriteLine(); |
| 67 | + int[] arr4 = new int[10000]; |
| 68 | + ArraySorting.IntArrayGenerate(arr4, 12); |
| 69 | + watch.Start(); |
| 70 | + ArraySorting.IntArrayShellSortNaive(arr4); |
| 71 | + watch.Stop(); |
| 72 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 73 | + WriteLine(new string(' ', 10) + "Shell Sort: {0:F3}", elapsedTime); |
| 74 | + |
| 75 | + WriteLine(); |
| 76 | + watch.Reset(); |
| 77 | + Write(new string('-', 30)); |
| 78 | + Write("Sort [Quicksort a.k.a. Partition Sort]"); |
| 79 | + Write(new string('-', 30)); |
| 80 | + WriteLine(); |
| 81 | + int[] arr5 = new int[10000]; |
| 82 | + ArraySorting.IntArrayGenerate(arr5, 12); |
| 83 | + watch.Start(); |
| 84 | + ArraySorting.IntArrayQuickSort(arr5); |
| 85 | + watch.Stop(); |
| 86 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 87 | + WriteLine(new string(' ', 10) + "Quicksort Sort: {0:F3}", elapsedTime); |
| 88 | + |
| 89 | + |
| 90 | + WriteLine(); |
| 91 | + watch.Reset(); |
| 92 | + Write(new string('-', 30)); |
| 93 | + Write("Sort [Merge Sort Recursive]"); |
| 94 | + Write(new string('-', 30)); |
| 95 | + WriteLine(); |
| 96 | + int[] arr6 = new int[10000]; |
| 97 | + ArraySorting.IntArrayGenerate(arr5, 12); |
| 98 | + watch.Start(); |
| 99 | + MergeSort_Recursive(arr6, 0, arr6.Length - 1); |
| 100 | + watch.Stop(); |
| 101 | + elapsedTime = watch.ElapsedMilliseconds / 1000.0; |
| 102 | + WriteLine(new string(' ', 10) + "Merge Sort Recursive: {0:F3}", elapsedTime); |
| 103 | + } |
| 104 | + |
| 105 | + public static void IntArrayGenerate(int[] data, int randomSeed) |
| 106 | + { |
| 107 | + Random r = new Random(randomSeed); |
| 108 | + for (int i = 0; i < data.Length; i++) |
| 109 | + data[i] = r.Next(); |
| 110 | + } |
| 111 | + private static void Swap(ref int x, ref int y) |
| 112 | + { |
| 113 | + var temp = x; |
| 114 | + x = y; |
| 115 | + y = temp; |
| 116 | + } |
| 117 | + |
| 118 | + #region Bubble Sort |
| 119 | + public static void BubbleSort(int[] a, int type = 0) |
| 120 | + { |
| 121 | + //WriteLine(string.Join(",", a)); |
| 122 | + for (var i = 1; i <= a.Length - 1; ++i) |
| 123 | + { |
| 124 | + for (var j = 0; j < a.Length - i; ++j) |
| 125 | + { |
| 126 | + if (type == 0) |
| 127 | + { |
| 128 | + if (a[j] > a[j + 1]) |
| 129 | + { |
| 130 | + Swap(ref a[j], ref a[j + 1]); |
| 131 | + } |
| 132 | + } |
| 133 | + else |
| 134 | + { |
| 135 | + if (a[j] < a[j + 1]) |
| 136 | + { |
| 137 | + Swap(ref a[j], ref a[j + 1]); |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + //WriteLine(string.Join(",", a)); |
| 143 | + } |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | + #endregion |
| 148 | + |
| 149 | + #region Selection Sort |
| 150 | + /* |
| 151 | + * REFFERENCE : https://www.tutorialspoint.com/data_structures_algorithms/selection_sort_algorithm.htm |
| 152 | + * The Selection Sort algorithm works to minimize the amount of data movement, hence the number of Swap() calls. |
| 153 | + * CREDIT : https://www.tutorialspoint.com/data_structures_algorithms/selection_sort_algorithm.htm |
| 154 | + */ |
| 155 | + public static int IntArrayMin(int[] data, int start) |
| 156 | + { |
| 157 | + var minPos = start; |
| 158 | + for (var pos = start + 1; pos < data.Length; pos++) |
| 159 | + if (data[pos] < data[minPos]) |
| 160 | + minPos = pos; |
| 161 | + return minPos; |
| 162 | + } |
| 163 | + |
| 164 | + public static void IntArraySelectionSort(int[] data) |
| 165 | + { |
| 166 | + //WriteLine(string.Join(",", data)); |
| 167 | + for (var i = 0; i < data.Length - 1; i++) |
| 168 | + { |
| 169 | + var k = IntArrayMin(data, i); |
| 170 | + if (i != k) |
| 171 | + Swap(ref data[i], ref data[k]); |
| 172 | + } |
| 173 | + //WriteLine(string.Join(",", data)); |
| 174 | + |
| 175 | + } |
| 176 | + #endregion |
| 177 | + |
| 178 | + #region Insertion Sort |
| 179 | + /* |
| 180 | + * REFFERENCE : https://www.tutorialspoint.com/data_structures_algorithms/bubble_sort_algorithm.htm |
| 181 | + * REFFERENCE : https://www.tutorialspoint.com/data_structures_algorithms/insertion_sort_algorithm.htm |
| 182 | + * In the Insertion Sort algorithm, we build a sorted list from the bottom of the array. We repeatedly insert the next element into the sorted part of the array by sliding it down (using our familiar Swap() method) to its proper position. |
| 183 | + * |
| 184 | + * This will require as many exchanges as Bubble Sort, since only one inversion is removed per exchange. |
| 185 | + * So Insertion Sort also requires O(N2)O(N2) exchanges. |
| 186 | + * On average Insertion Sort requires only half as many comparisons as Bubble Sort, |
| 187 | + * since the average distance an element must move for random input is one-half the length of the sorted portion. |
| 188 | + * CREDIT : http://anh.cs.luc.edu/170/notes/CSharpHtml/sorting.html |
| 189 | + */ |
| 190 | + public static void IntArrayInsertionSort(int[] data) |
| 191 | + { |
| 192 | + //WriteLine(string.Join(",", data)); |
| 193 | + for (var j = 1; j < data.Length; j++) |
| 194 | + { |
| 195 | + for (var i = j; i > 0 && data[i] < data[i - 1]; i--) |
| 196 | + { |
| 197 | + Swap(ref data[i], ref data[i - 1]); |
| 198 | + } |
| 199 | + } |
| 200 | + //WriteLine(string.Join(",", data)); |
| 201 | + } |
| 202 | + |
| 203 | + #endregion |
| 204 | + |
| 205 | + #region Shell Sort |
| 206 | + /* |
| 207 | + * REFFERENCE : https://www.tutorialspoint.com/data_structures_algorithms/shell_sort_algorithm.htm |
| 208 | + * CREDIT : http://anh.cs.luc.edu/170/notes/CSharpHtml/sorting.html |
| 209 | + */ |
| 210 | + public static void IntArrayShellSort(int[] data, int[] intervals) |
| 211 | + { |
| 212 | + // The intervals for the shell sort must be sorted, ascending |
| 213 | + for (var k = intervals.Length - 1; k >= 0; k--) |
| 214 | + { |
| 215 | + int interval = intervals[k]; |
| 216 | + for (var m = 0; m < interval; m++) |
| 217 | + { |
| 218 | + for (var j = m + interval; j < data.Length; j += interval) |
| 219 | + { |
| 220 | + for (var i = j; i >= interval && data[i] < data[i - interval]; i -= interval) |
| 221 | + { |
| 222 | + Swap(ref data[i], ref data[i - interval]); |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | + } |
| 227 | + } |
| 228 | + static int[] GenerateIntervals(int n) |
| 229 | + { |
| 230 | + if (n < 2) |
| 231 | + { // no sorting will be needed |
| 232 | + return new int[0]; |
| 233 | + } |
| 234 | + var t = Math.Max(1, (int)Math.Log(n, 3) - 1); |
| 235 | + var intervals = new int[t]; |
| 236 | + intervals[0] = 1; |
| 237 | + for (var i = 1; i < t; i++) |
| 238 | + intervals[i] = 3 * intervals[i - 1] + 1; |
| 239 | + return intervals; |
| 240 | + } |
| 241 | + |
| 242 | + public static void IntArrayShellSortNaive(int[] data) |
| 243 | + { |
| 244 | + //WriteLine(string.Join(",", data)); |
| 245 | + var intervals = GenerateIntervals(data.Length); |
| 246 | + IntArrayShellSort(data, intervals); |
| 247 | + //WriteLine(string.Join(",", data)); |
| 248 | + } |
| 249 | + #endregion |
| 250 | + |
| 251 | + #region Quicksort a.k.a. Partition Sort |
| 252 | + /* |
| 253 | + * REFFERENCE : https://www.tutorialspoint.com/data_structures_algorithms/quick_sort_algorithm.htm |
| 254 | + * Quicksort is a rather interesting case. It is often perceived to be one of the best sorting algorithms but, in practice, has a worst case performance also on the order O(N2)O(N2). |
| 255 | + * When the data are randomly sorted (as in our experiments) it does better at O(NlogN)O(NlogN). |
| 256 | + * CREDIT : http://anh.cs.luc.edu/170/notes/CSharpHtml/sorting.html |
| 257 | + */ |
| 258 | + public static void IntArrayQuickSort(int[] data, int l, int r) |
| 259 | + { |
| 260 | + var i = l; |
| 261 | + var j = r; |
| 262 | + |
| 263 | + var x = data[(l + r) / 2]; /* find pivot item */ |
| 264 | + while (true) |
| 265 | + { |
| 266 | + while (data[i] < x) |
| 267 | + i++; |
| 268 | + while (x < data[j]) |
| 269 | + j--; |
| 270 | + if (i <= j) |
| 271 | + { |
| 272 | + Swap(ref data[i], ref data[j]); |
| 273 | + i++; |
| 274 | + j--; |
| 275 | + } |
| 276 | + if (i > j) |
| 277 | + break; |
| 278 | + } |
| 279 | + if (l < j) |
| 280 | + IntArrayQuickSort(data, l, j); |
| 281 | + if (i < r) |
| 282 | + IntArrayQuickSort(data, i, r); |
| 283 | + } |
| 284 | + |
| 285 | + public static void IntArrayQuickSort(int[] data) |
| 286 | + { |
| 287 | + // WriteLine(string.Join(",", data)); |
| 288 | + IntArrayQuickSort(data, 0, data.Length - 1); |
| 289 | + // WriteLine(string.Join(",", data)); |
| 290 | + } |
| 291 | + |
| 292 | + #endregion |
| 293 | + |
| 294 | + #region Merge Sort Recursive |
| 295 | + /* |
| 296 | + * Refference : https://www.tutorialspoint.com/data_structures_algorithms/merge_sort_algorithm.htm |
| 297 | + * Credig : http://www.softwareandfinance.com/CSharp/MergeSort_Recursive.html |
| 298 | + */ |
| 299 | + public static void DoMerge(int[] numbers, int left, int mid, int right) |
| 300 | + { |
| 301 | + int[] temp = new int[numbers.Length]; |
| 302 | + int i; |
| 303 | + |
| 304 | + var leftEnd = (mid - 1); |
| 305 | + var tmpPos = left; |
| 306 | + var numElements = (right - left + 1); |
| 307 | + |
| 308 | + while ((left <= leftEnd) && (mid <= right)) |
| 309 | + { |
| 310 | + if (numbers[left] <= numbers[mid]) |
| 311 | + temp[tmpPos++] = numbers[left++]; |
| 312 | + else |
| 313 | + temp[tmpPos++] = numbers[mid++]; |
| 314 | + } |
| 315 | + |
| 316 | + while (left <= leftEnd) |
| 317 | + temp[tmpPos++] = numbers[left++]; |
| 318 | + |
| 319 | + while (mid <= right) |
| 320 | + temp[tmpPos++] = numbers[mid++]; |
| 321 | + |
| 322 | + for (i = 0; i < numElements; i++) |
| 323 | + { |
| 324 | + numbers[right] = temp[right]; |
| 325 | + right--; |
| 326 | + } |
| 327 | + } |
| 328 | + |
| 329 | + public static void MergeSort_Recursive(int[] numbers, int left, int right) |
| 330 | + { |
| 331 | + if (right > left) |
| 332 | + { |
| 333 | + var mid = (right + left) / 2; |
| 334 | + MergeSort_Recursive(numbers, left, mid); |
| 335 | + MergeSort_Recursive(numbers, (mid + 1), right); |
| 336 | + |
| 337 | + DoMerge(numbers, left, (mid + 1), right); |
| 338 | + } |
| 339 | + } |
| 340 | + #endregion |
| 341 | + } |
| 342 | +} |
0 commit comments