From f4addcd9a443bf4e6b1b1318ecc4d1fad061e8fc Mon Sep 17 00:00:00 2001 From: Brandon Gastelo <shady1765@gmail.com> Date: Fri, 19 Oct 2018 22:54:20 -0700 Subject: [PATCH] Added support for using merge sort on generic objects implementing the Comparable interface. Added merge sort implementations for missing primitive types: byte, char, float, short, and long. Added test cases for each type. --- .../allalgorithms/sorting/MergeSort.java | 815 ++++++++++++++---- .../allalgorithms/sorting/MergeSortTest.java | 56 +- 2 files changed, 700 insertions(+), 171 deletions(-) diff --git a/src/main/java/com/abranhe/allalgorithms/sorting/MergeSort.java b/src/main/java/com/abranhe/allalgorithms/sorting/MergeSort.java index afb46ec..d47c625 100644 --- a/src/main/java/com/abranhe/allalgorithms/sorting/MergeSort.java +++ b/src/main/java/com/abranhe/allalgorithms/sorting/MergeSort.java @@ -23,179 +23,654 @@ package com.abranhe.allalgorithms.sorting; +import java.util.Arrays; + /** - * The class {@code MergeSort} contains methods for performing - * a poor :( merge sort algorithm of Integers and Doubles + * The class {@code MergeSort} contains methods for performing a poor :( merge + * sort algorithm of Integers and Doubles * - * @author Carlos Abraham Hernandez - * @since 0.0.1 + * @author Carlos Abraham Hernandez + * @author Brandon Gastelo + * @since 0.0.1 */ public class MergeSort { - /** - * This class should not be instantiated. - */ - private MergeSort() { } - - /** - * Merges two subarrays of arr[]. - * First subarray is arr[l..m] - * Second subarray is arr[m+1..r] - * - * @param arr array - * @param l index to start sorting - * @param m index of the middle of the array - * @param r index to finish sorting - */ - private static void merge(int arr[], int l, int m, int r) { - - int n1 = m - l + 1; - int n2 = r - m; - - int L[] = new int [n1]; - int R[] = new int [n2]; - - System.arraycopy(arr, l + 0, L, 0, n1); - - for (int j=0; j<n2; ++j) - R[j] = arr[m + 1+ j]; - - int i = 0, j = 0; - - int k = l; - while (i < n1 && j < n2) { - if (L[i] <= R[j]) { - arr[k] = L[i]; - i++; - } - else { - arr[k] = R[j]; - j++; - } - k++; - } - - while (i < n1) { - arr[k] = L[i]; - i++; - k++; - } - - while (j < n2) { - arr[k] = R[j]; - j++; - k++; - } - } - - /** - * Merges two subarrays of arr[]. type double - * First subarray is arr[l..m] - * Second subarray is arr[m+1..r] - * - * @param arr array - * @param l index to start sorting - * @param m index of the middle of the array - * @param r index to finish sorting - */ - private static void merge(double arr[], int l, int m, int r) { - - int n1 = m - l + 1; - int n2 = r - m; - - double L[] = new double [n1]; - double R[] = new double [n2]; - - System.arraycopy(arr, l + 0, L, 0, n1); - - for (int j=0; j<n2; ++j) - R[j] = arr[m + 1+ j]; - - int i = 0, j = 0; - - int k = l; - while (i < n1 && j < n2) { - if (L[i] <= R[j]) { - arr[k] = L[i]; - i++; - } - else { - arr[k] = R[j]; - j++; - } - k++; - } - - while (i < n1) { - arr[k] = L[i]; - i++; - k++; - } - - while (j < n2) { - arr[k] = R[j]; - j++; - k++; - } - } - - /** - * Sort array of integers - * @param arr array - * @param l index to start sorting - * @param r index to finish sorting - */ - private static void sort(int arr[], int l, int r) { - if (l < r) { - - int m = (l+r)/2; - - sort(arr, l, m); - sort(arr , m+1, r); - - merge(arr, l, m, r); - } - } - - /** - * Sort array of doubles - * @param arr array - * @param l index to start sorting - * @param r index to finish sorting - */ - private static void sort(double arr[], int l, int r) { - if (l < r) { - - int m = (l+r)/2; - - sort(arr, l, m); - sort(arr , m+1, r); - - merge(arr, l, m, r); - } - } - - /** - * The sort method of the {@code MergeSort} class - * takes an array of {@code Integers} an sort it. - * - * @param arr array of integers to be sorted - */ - public static void sort(int arr[]) { - int l = 0; - int r = arr.length-1; - sort(arr, l, r); - } - - /** - * The sort method of the {@code MergeSort} class - * takes an array of {@code Double} an sort it. - * - * @param arr array of doubles to be sorted - */ - public static void sort(double arr[]) { - int l = 0; - int r = arr.length-1; - sort(arr, l, r); - } + /** + * This class should not be instantiated. + */ + private MergeSort() { + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(byte arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + byte L[] = new byte[n1]; + byte R[] = new byte[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(char arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + char L[] = new char[n1]; + char R[] = new char[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. type double First subarray is arr[l..m] Second + * subarray is arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(double arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + double L[] = new double[n1]; + double R[] = new double[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(float arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + float L[] = new float[n1]; + float R[] = new float[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(int arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + int L[] = new int[n1]; + int R[] = new int[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(long arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + long L[] = new long[n1]; + long R[] = new long[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. First subarray is arr[l..m] Second subarray is + * arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static void merge(short arr[], int l, int m, int r) { + + int n1 = m - l + 1; + int n2 = r - m; + + short L[] = new short[n1]; + short R[] = new short[n2]; + + System.arraycopy(arr, l + 0, L, 0, n1); + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 + j]; + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i] <= R[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * Merges two subarrays of arr[]. generic type First subarray is arr[l..m] + * Second subarray is arr[m+1..r] + * + * @param arr array + * @param l index to start sorting + * @param m index of the middle of the array + * @param r index to finish sorting + */ + private static <T extends Comparable<? super T>> void merge(T arr[], int l, int m, int r) { + int n1 = m - l + 1; + int n2 = r - m; + + T L[] = Arrays.copyOfRange(arr, l, l + n1); + T R[] = Arrays.copyOfRange(arr, m + 1, r + 1); + + int i = 0, j = 0; + + int k = l; + while (i < n1 && j < n2) { + if (L[i].compareTo(R[j]) <= 0) { + arr[k] = L[i]; + i++; + } else { + arr[k] = R[j]; + j++; + } + k++; + } + + while (i < n1) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < n2) { + arr[k] = R[j]; + j++; + k++; + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of {@code Byte} + * an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(byte arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of bytes + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(byte arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Character} an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(char arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of characters + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(char arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Double} an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(double arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of doubles + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(double arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Float} an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(float arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of floats + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(float arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Integers} an sort it. + * + * @param arr array of integers to be sorted + */ + public static void sort(int arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of integers + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(int arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of {@code Long} + * an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(long arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of longs + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(long arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Short} an sort it. + * + * @param arr array of doubles to be sorted + */ + public static void sort(short arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of shorts + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static void sort(short arr[], int l, int r) { + if (l < r) { + + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } + + /** + * The sort method of the {@code MergeSort} class takes an array of + * {@code Comparable} objects and sorts them. + * + * @param arr array of objects to be sorted + */ + public static <T extends Comparable<? super T>> void sort(T arr[]) { + int l = 0; + int r = arr.length - 1; + sort(arr, l, r); + } + + /** + * Sort array of generic objects + * + * @param arr array + * @param l index to start sorting + * @param r index to finish sorting + */ + private static <T extends Comparable<? super T>> void sort(T[] arr, int l, int r) { + if (l < r) { + int m = (l + r) / 2; + + sort(arr, l, m); + sort(arr, m + 1, r); + + merge(arr, l, m, r); + } + } } diff --git a/src/test/java/com/abranhe/allalgorithms/sorting/MergeSortTest.java b/src/test/java/com/abranhe/allalgorithms/sorting/MergeSortTest.java index 04e2bf5..1d98943 100644 --- a/src/test/java/com/abranhe/allalgorithms/sorting/MergeSortTest.java +++ b/src/test/java/com/abranhe/allalgorithms/sorting/MergeSortTest.java @@ -27,6 +27,42 @@ public class MergeSortTest { + private byte[] bytesArr = {7, -3, 0, 30, 19, 27}; + private byte[] expectedBytesArr = {-3, 0, 7, 19, 27, 30}; + + @Test public void sortBytes() { + MergeSort.sort(bytesArr); + assertArrayEquals("Sort Bytes", expectedBytesArr, bytesArr); + + } + + private char[] charsArr = {7, 3, 0, 30, 19, 27}; + private char[] expectedCharsArr = {0, 3, 7, 19, 27, 30}; + + @Test public void sortChars() { + MergeSort.sort(charsArr); + assertArrayEquals("Sort Chars", expectedCharsArr, charsArr); + + } + + private short[] shortsArr = {7, -3, 0, 30, 19, 27}; + private short[] expectedShortsArr = {-3, 0, 7, 19, 27, 30}; + + @Test public void sortShorts() { + MergeSort.sort(shortsArr); + assertArrayEquals("Sort Shorts", expectedShortsArr, shortsArr); + + } + + private long[] longsArr = {7, -3, 0, 30, 19, 27}; + private long[] expectedLongsArr = {-3, 0, 7, 19, 27, 30}; + + @Test public void sortLongs() { + MergeSort.sort(longsArr); + assertArrayEquals("Sort Longs", expectedLongsArr, longsArr); + + } + private int[] integersArr = {7, -3, 0, 30, 19, 27}; private int[] expectedIntegersArr = {-3, 0, 7, 19, 27, 30}; @@ -43,4 +79,22 @@ public class MergeSortTest { MergeSort.sort(doublesArr); assertArrayEquals("Sort Doubles", expectedDoublesArr, doublesArr, 7); } -} \ No newline at end of file + + private String[] stringsArr = {"Dog", "Cat", "Car", "Tree", "House", "Java"}; + private String[] expectedStringsArr = {"Car", "Cat", "Dog", "House", "Java" , "Tree"}; + + @Test public void sortStrings() { + MergeSort.sort(stringsArr); + assertArrayEquals("Sort Strings", stringsArr, expectedStringsArr); + } + + private float[] floatsArr = {7f, 1f, 9f, 0f, 7f, -3f}; + private float[] expectedFloatsArr = {-3f, 0f, 1f, 7f, 7f, 9f}; + + @Test public void sortFloats() { + MergeSort.sort(floatsArr); + assertArrayEquals("Sort Floats", expectedFloatsArr, floatsArr, 7); + } + + +}