Advertisement
Elandiro

sorting

Mar 14th, 2013
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.11 KB | None | 0 0
  1. import java.util.Random;
  2.  
  3. /**
  4. * A class defining a number of sorting algorithms.
  5. *
  6. * @author fill in your name here
  7. */
  8. public class SortingAlgorithms {
  9. int numberOfComparisons;
  10.  
  11. public SortingAlgorithms() {
  12. resetComparisonCounter();
  13. }
  14.  
  15. public void resetComparisonCounter() {
  16. numberOfComparisons = 0;
  17. }
  18.  
  19. private void increaseComparisonCounter() {
  20. numberOfComparisons++;
  21. }
  22.  
  23. public int getNumberOfComparisonsMade() {
  24. return numberOfComparisons;
  25. }
  26.  
  27. private static <T extends Comparable<T>> void exch(T[] array, int a, int b) {
  28. T temp = array[a];
  29. array[a] = array[b];
  30. array[b] = temp;
  31. }
  32.  
  33. private static int charAt(String string, int d){
  34. if (d < string.length()) return string.charAt(d); else return -1;
  35. }
  36.  
  37. private static Integer[] getArrayOfNSubsequentElements(int n) {
  38. Integer[] array = new Integer[n];
  39. for (int i = 0; i < n; ++i)
  40. array[i] = i;
  41. return array;
  42. }
  43.  
  44. private <T extends Comparable<T>> boolean less(T v, T w) {
  45. increaseComparisonCounter();
  46. return v.compareTo(w) < 0;
  47. }
  48.  
  49.  
  50.  
  51. private static <T extends Comparable<T>> void randomPermutation(T[] array) {
  52. Random randomGenerator = new Random();
  53. int randomIndex;
  54. // This loop makes sure we don't leave any elements untouched. Elements
  55. // can be swapped back to their original position, but that is of course
  56. // part of randomness.
  57. for (int i = 0; i < array.length; ++i) {
  58. randomIndex = randomGenerator.nextInt(array.length);
  59. exch(array,i,randomIndex);
  60. }
  61. }
  62.  
  63. private static String[] getMRandomStringsOfLengthN(int m, int n) {
  64. Random randomGenerator = new Random();
  65. String output[] = new String[m];
  66. for (int i = 0; i < m; ++i) {
  67. String o = "";
  68. for (int j = 0; j < n; ++j) {
  69. o += randomGenerator.nextInt(10);
  70. }
  71. output[i] = o;
  72. }
  73. return output;
  74. }
  75.  
  76. /**
  77. * Sorts the given array using selection sort.
  78. *
  79. * @return The number of comparisons (i.e. calls to compareTo) performed by the algorithm.
  80. */
  81. public <T extends Comparable<T>> int selectionSort(T[] array) {
  82. int len = array.length;
  83. for (int i = 0; i < len; i++) {
  84. int min = i;
  85. for (int j = i+1; j < len; j++) {
  86. if (less(array[j],array[min]))
  87. min = j;
  88. }
  89. exch(array, i, min);
  90. }
  91. return getNumberOfComparisonsMade();
  92. }
  93.  
  94. /**
  95. * Sorts the given array using insertion sort.
  96. *
  97. * @return The number of comparisons (i.e. calls to compareTo) performed by the algorithm.
  98. */
  99. public <T extends Comparable<T>> int insertionSort(T[] array) {
  100. int len = array.length;
  101. for (int i = 1; i < len; i++) {
  102. for (int j = i; j > 0 && less(array[j], array[j-1]); j--)
  103. exch(array, j, j-1);
  104. }
  105. return getNumberOfComparisonsMade();
  106. }
  107.  
  108. /**
  109. * Sorts the given array using (2-way) merge sort.
  110. *
  111. * HINT: Java does not supporting creating generic arrays (because the compiler uses type erasure for generic types).
  112. * For example, the statement "T[] aux = new T[100];" is rejected by the compiler.
  113. * Use the statement "T[] aux = (T[]) new Comparable[100];" instead.
  114. * Add an "@SuppressWarnings("unchecked")" annotation to prevent the compiler from reporting a warning.
  115. * Consult the following url for more information on generics in Java:
  116. * http://download.oracle.com/javase/tutorial/java/generics/index.html
  117. *
  118. * @return The number of comparisons (i.e. calls to compareTo) performed by the algorithm.
  119. */
  120. @SuppressWarnings("unchecked")
  121. public <T extends Comparable<T>> int mergeSort(T[] array) {
  122. T[] aux = (T[]) new Comparable[array.length];
  123. mergeSort(array, aux, 0, array.length - 1);
  124. return getNumberOfComparisonsMade();
  125. }
  126.  
  127. private <T extends Comparable<T>> void mergeSort(T[] array, T[] aux, int low, int high) {
  128. if (high <= low) return;
  129. int mid = low + (high - low)/2;
  130. mergeSort(array, aux, low, mid);
  131. mergeSort(array, aux, mid+1, high);
  132. merge(array, aux, low, mid, high);
  133. }
  134.  
  135. private <T extends Comparable<T>> void merge(T[] array, T[] aux, int low, int mid, int high) {
  136. int i = low, j = mid + 1;
  137.  
  138. for (int k = low; k <= high; k++)
  139. aux[k] = array[k];
  140.  
  141. for (int k = low; k <= high; k++) {
  142. if (i > mid)
  143. array[k] = aux[j++];
  144. else if (j > high)
  145. array[k] = aux[i++];
  146. else if (less(aux[j], aux[i]))
  147. array[k] = aux[j++];
  148. else
  149. array[k] = aux[i++];
  150. }
  151. }
  152.  
  153. /**
  154. * Sorts the given array using quick sort. Do NOT perform a random shuffle.
  155. *
  156. * @return The number of comparisons (i.e. calls to compareTo) performed by the algorithm.
  157. */
  158. public <T extends Comparable<T>> int quickSort(T[] array) {
  159. quickSort(array, 0, array.length-1);
  160. return getNumberOfComparisonsMade();
  161. }
  162.  
  163. /**
  164. * Sorts the given part of the array using quick sort.
  165. *
  166. * @return The number of data moves, used for kWayMergeSort.
  167. */
  168. private <T extends Comparable<T>> int quickSort(T[] array, int low, int high) {
  169. if (high <= low)
  170. return 0;
  171. int[] values = partition(array, low, high);
  172. int j = values[0];
  173. quickSort(array, low, j-1);
  174. quickSort(array, j+1, high);
  175. return values[1];
  176. }
  177.  
  178. private <T extends Comparable<T>> int[] partition(T[] a, int low, int high) {
  179. int i = low, j = high+1, exch = 0;
  180. T v = a[low];
  181. while (true) {
  182. while (less(a[++i], v))
  183. if (i == high) break;
  184. while (less(v, a[--j]))
  185. if (j == low) break;
  186. if (i >= j) break;
  187. exch += 2;
  188. exch(a, i, j);
  189. }
  190. exch += 2;
  191. exch(a, low, j);
  192. int[] returnValues = new int[2];
  193. returnValues[0] = j;
  194. returnValues[1] = exch;
  195. return returnValues;
  196. }
  197.  
  198. /**
  199. * Sorts the given array using k-way merge sort. The implementation can assume that k is at least 2.
  200. * k is the number of the number of subarrays (at each level) that must be separately sorted via a recursive call and merged via a k-way merge.
  201. * For example, if k equals 3, then the array must be subdivided into three subarrays that are each sorted by 3-way merge sort. After the 3 sub-
  202. * arrays, these sub-arrays are combined via a 3-way merge.
  203. *
  204. * Note that if k is larger than the length of the array (or larger than the length of a sub-array in a recursive call),
  205. * then the implementation is allowed sort that sub-array using quick sort.
  206. *
  207. * @return An non-null array of length 2. The first element of this array is the number of comparisons (i.e. calls to compareTo) performed by
  208. * the algorithm, while the second element is the number of data moves.
  209. */
  210. @SuppressWarnings("unchecked")
  211. public <T extends Comparable<T>> int[] kWayMergeSort(T[] array, int k) {
  212. T[] aux = (T[]) new Comparable[array.length];
  213. int numberOfMoves = kWayMergeSort(array, aux, k, 0, array.length - 1);
  214. int[] returnValue = { getNumberOfComparisonsMade(), numberOfMoves };
  215. return returnValue;
  216. }
  217.  
  218. private <T extends Comparable<T>> int kWayMergeSort(T[] array, T[] aux, int k, int low, int high) {
  219. int numberOfMoves = 0;
  220. if (k > (high - low + 1))
  221. numberOfMoves = quickSort(array, low, high);
  222. else if (high - low > 1) {
  223. int position = low, length;
  224. int[] startingElements = new int[k];
  225. int[] endElements = new int[k];
  226. for (int i = k; i > 0; i--) {
  227. length = (high - position + 1) / i;
  228. startingElements[k-i] = position;
  229. numberOfMoves += kWayMergeSort(array, aux, k, position, position + length - 1);
  230. position = position + length;
  231. endElements[k-i] = position;
  232. }
  233. numberOfMoves += kWayMerge(array, aux, low, high, startingElements, endElements);
  234. }
  235. return numberOfMoves;
  236. }
  237.  
  238. private <T extends Comparable<T>> int kWayMerge(T[] array, T[] aux, int low, int high, int[] startingElements, int[] endElements) {
  239. int numberOfMoves = high - low + 1; // To avoid doing +1 every time in the following loop
  240. for (int i = low; i <= high; ++i)
  241. aux[i] = array[i];
  242.  
  243. for (int i = low; i <= high; ++i) {
  244. T valueOfLowest = null;
  245. int elementCounter = 0;
  246. for (int j = 0; j < startingElements.length; ++j) {
  247. int positionInArray = startingElements[j];
  248. if (positionInArray >= endElements[j])
  249. continue;
  250. if (valueOfLowest == null || less(aux[positionInArray], valueOfLowest)) {
  251. valueOfLowest = aux[positionInArray];
  252. elementCounter = j;
  253. }
  254. }
  255. numberOfMoves++;
  256. array[i] = valueOfLowest;
  257. startingElements[elementCounter]++;
  258. }
  259. return numberOfMoves;
  260. }
  261.  
  262. /**
  263. * Sorts the given array of strings using LSD sort. Each string in the input array has length W.
  264. *
  265. * @return the number of arrays accesses performed by the algorithm
  266. */
  267. public int lsdSort(String[] array, int W) {
  268. int len = array.length;
  269. int alphabetSize = 256;
  270. String[] aux = new String[len];
  271. for (int d = W-1; d >= 0; d--) {
  272. int[] count = new int[alphabetSize+1];
  273. for (int i = 0; i < len; i++)
  274. count[charAt(array[i],d) + 1]++; // charAt() gives the ascii value, so we have to do -48.
  275. for (int r = 0; r < alphabetSize; r++)
  276. count[r+1] += count[r];
  277. for (int i = 0; i < len; i++)
  278. aux[count[charAt(array[i],d)]++] = array[i];
  279. for (int i = 0; i < len; i++)
  280. array[i] = aux[i];
  281. }
  282. return len + W * (alphabetSize + len * 2 + alphabetSize * 2 + len * 3 + len * 2);
  283. }
  284.  
  285. /**
  286. * Sorts the given array of strings using MSD sort. Do NOT use a cutoff for small subarrays.
  287. *
  288. * @return the number of characters examined by the algorithm
  289. */
  290. public int msdSort(String[] array) {
  291. int N = array.length;
  292. String[] aux = new String[N];
  293. return msdSort(array, aux, 0, N-1, 0);
  294. }
  295.  
  296. private int msdSort(String[] array, String[] aux, int low, int high, int d) {
  297. if (high <= low)
  298. return 0;
  299. int charsExamined = 0;
  300. int alphabetSize = 256;
  301. int[] count = new int[alphabetSize+2];
  302. for (int i = low; i <= high; i++)
  303. count[charAt(array[i], d) + 2]++;
  304. for (int r = 0; r < alphabetSize+1; r++)
  305. count[r+1] += count[r];
  306. for (int i = low; i <= high; i++)
  307. aux[count[charAt(array[i], d) + 1]++] = array[i];
  308. for (int i = low; i <= high; i++)
  309. array[i] = aux[i - low];
  310. charsExamined = (high - low + 1);
  311. for (int r = 0; r < alphabetSize; r++)
  312. charsExamined += msdSort(array, aux, low + count[r], low + count[r+1] - 1, d+1);
  313. return charsExamined;
  314. }
  315.  
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement