Skip to content

Commit c7240ef

Browse files
authored
MergeSorter using Generics
1 parent 419765c commit c7240ef

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Merge Sorter
3+
* @author Samy Rezzag
4+
* Pseudocode adaptation from Thomas H. Cormens' Introduction to Algoirthms Third Edition.
5+
*/
6+
7+
/*
8+
* The MergeSorter class demonstrates the divide-and-conquer MergeSort algorithm.
9+
*/
10+
11+
public class MergeSorter<T> {
12+
13+
/*
14+
* Initial point of entry. Public Sort of type T takes an array parameter of
15+
* type Comparable<? extends T>[]. This checks for null and base cases. If
16+
* neither are found it will pass it to the private overloaded method for
17+
* further sorting.
18+
*
19+
* @param Comparable<? extends T>[] items
20+
*
21+
* @throws NullPointerException if items is a null array, or has null value.
22+
*/
23+
24+
public static <T> void sort(Comparable<? extends T>[] items) {
25+
// Test if items is null.
26+
if (items == null) {
27+
throw new NullPointerException("Invalid Array. Array cannot be null.");
28+
// Test if array is empty, or of size 1 and not [null].
29+
} else if (items.length == 0 || (items.length == 1 && items[0] != null)) {
30+
return;
31+
} else {
32+
// Scan array for any additional null values.
33+
for (int i = 0; i < items.length; i++) {
34+
if (items[i] == null) {
35+
throw new NullPointerException("Invalid Array. Array values cannot be null.");
36+
}
37+
}
38+
// Pass valid array for sorting.
39+
sort(items, 0, items.length - 1);
40+
}
41+
}
42+
43+
/*
44+
* The private sort method calculates low, middle, and high indices of the
45+
* Comparable array. If the start index is lower than the high index, it will
46+
* continue to divide the array recursively and merge as needed.
47+
*
48+
* @param Comparable<? extends T>[] items, int low, int high
49+
*
50+
*/
51+
52+
private static <T> void sort(Comparable<? extends T>[] items, int low, int high) {
53+
if (low < high) {
54+
int mid = (low + high) / 2;
55+
sort(items, low, mid);
56+
sort(items, mid + 1, high);
57+
merge(items, low, mid, high);
58+
}
59+
}
60+
61+
/*
62+
* The merge method needed some tweaking in terms the of the parameter. Java
63+
* doesn't allow for generic arrays to be created. Type casting is used as a
64+
* workaround to this. Items has to be truncated to a raw type of comparable.
65+
* Instead of creating left and right subarrays to merge, indices of the index
66+
* array are used to traverse the array and compare one side to the other. A
67+
* temporary Array is used to collect and store the sorted values, and are then
68+
* casted in order to the items array. We use the temporary array to avoid
69+
* overwriting the items array which we are referencing.
70+
*
71+
* @param Comparable items, int low, int medium, int high
72+
*/
73+
74+
private static <T> void merge(Comparable[] items, int low, int mid, int high) {
75+
Object[] tempArr = new Object[high - low + 1];
76+
int i = low;
77+
int j = mid + 1;
78+
int k = 0;
79+
while (i <= mid && j <= high) {
80+
if (items[i].compareTo(items[j]) <= 0)
81+
tempArr[k] = items[i++];
82+
else
83+
tempArr[k] = items[j++];
84+
k++;
85+
}
86+
if (i <= mid && j > high) {
87+
while (i <= mid)
88+
tempArr[k++] = items[i++];
89+
} else {
90+
while (j <= high)
91+
tempArr[k++] = items[j++];
92+
}
93+
for (k = 0; k < tempArr.length; k++) {
94+
items[k + low] = (Comparable<?>) (tempArr[k]); // cast
95+
}
96+
}
97+
98+
/*
99+
* Main method used for testing various types of arrays to account for any
100+
* issues in live/production environment.
101+
*/
102+
103+
public static void main(String[] args) {
104+
105+
// Test Sort of Strings
106+
String[] sortWords = new String[] { "orange", "green", "blue", "red", "yellow", "purple" };
107+
MergeSorter.sort(sortWords);
108+
109+
// Test Sort of Integers
110+
Integer[] sortNumbers = new Integer[] { 5, 7, 3, 9, 4, 0, 1, 2, 8, 6 };
111+
MergeSorter.sort(sortNumbers);
112+
113+
// Test Sort of Empty Array
114+
Integer[] emptyArray = new Integer[0];
115+
MergeSorter.sort(emptyArray);
116+
117+
// Test Sort of Null Array
118+
Integer[] nullArray = null;
119+
MergeSorter.sort(nullArray);
120+
121+
// Test Sort of Null value in Array
122+
Integer[] nullValueInArray = new Integer[] { 1, 5, 4, null, 3, 2 };
123+
MergeSorter.sort(nullValueInArray);
124+
125+
// Test Sort of 1-Value Array
126+
Integer[] oneNull = new Integer[] { null };
127+
MergeSorter.sort(oneNull);
128+
129+
// Test Sort of 1-Value Array
130+
Integer[] oneArray = new Integer[] { 1 };
131+
MergeSorter.sort(oneArray);
132+
133+
// Test Sort of Strings + Integers
134+
String[] mixedArray = new String[] { "chicken", "5", "cow", "3", "horse", "1", "goat", "4", "sheep", "2" };
135+
MergeSorter.sort(mixedArray);
136+
137+
// Test Sort of Negative + Positive Integers.
138+
Integer[] negativeIntegers = new Integer[] { -5, 5, -4, 4, -3, 3, -2, 2, -1, 1, 0 };
139+
MergeSorter.sort(negativeIntegers);
140+
}
141+
}

0 commit comments

Comments
 (0)