-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMergeSort.java
138 lines (121 loc) · 3.96 KB
/
MergeSort.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import java.util.Random;
/**
* 08-722 Data Structures for Application Programmers.
*
* Lab 5 Comparing MergeSort with QuickSort
*
* A simple MergeSort implementation
*
* Andrew ID:rwan1
* @author Rui Wan
*/
public class MergeSort {
/**
* constant for SIZE of an array to sort.
*/
private static final int SIZE = 100000;
/**
* Random numbers.
*/
private static Random rand = new Random();
/**
* Test program to check merge sort and its running time.
* @param args arguments
*/
public static void main(String[] args) {
int[] array = new int[SIZE];
for (int i = 0; i < SIZE; i++) array[i] = rand.nextInt();
//for (int i = 0; i < SIZE; i++) array[i] = SIZE - i;
Stopwatch timer = new Stopwatch();
mergeSort(array);
System.out.println(
"Time taken to sort " + SIZE + " elements (Merge Sort): " + timer.elapsedTime() + " milliseconds");
// to make sure sorting works
// add "-ea" vm argument
assert isSorted(array);
}
/**
* merge sort method.
* @param from input array to sort
*/
public static void mergeSort(int[] from) {
// create a new array
int[] to = new int[from.length];
mergeSort(from, to, 0, from.length - 1);
}
/**
* helper method to merge sort from (input) array using an auxiliary array.
* @param from input array to sort
* @param to auxiliary array to use
* @param left left boundary
* @param right right boundary
*/
private static void mergeSort(int[] from, int[] to, int left, int right) {
// base case
if (left >= right) {
return;
}
// recursive case
// find midpoint
int mid = left + (right - left) / 2;
// sort left half recursively
mergeSort(from, to, left, mid);
// sort right half recursively
mergeSort(from, to, mid + 1, right);
// merge them
merge(from, to, left, mid + 1, right);
}
/**
* Instead of creating multiple arrays, this merge works with only two arrays.
* @param from input array
* @param to auxiliary array to use during merge process
* @param leftPos starting point of left half
* @param rightPos starting point of right half
* @param rightBound upper bound of right half
*/
public static void merge(int[] from, int[] to, int leftPos, int rightPos, int rightBound) {
// throw new RuntimeException("Implement this method");
int leftStart = leftPos;
int leftEnd = rightPos - 1;
int rightStart = rightPos;
int rightEnd = rightBound;
int index = leftStart;
int size = rightEnd - leftStart + 1;
while (leftPos <= leftEnd && rightPos <= rightEnd) {
if (from[leftPos] < from[rightPos]) {
to[index] = from[leftPos];
leftPos++;
} else {
to[index] = from[rightPos];
rightPos++;
}
index++;
}
System.arraycopy(from, leftPos, to, index, leftEnd - leftPos + 1);
System.arraycopy(from, rightPos, to, index, rightEnd - rightPos + 1);
System.arraycopy(to, leftStart, from, leftStart, size);
}
/**
* A simple debugging program to check if array is sorted.
* @param array array to check
* @return true if sorted and false if not
*/
private static boolean isSorted(int[] array) {
return isSorted(array, 0, array.length - 1);
}
/**
* Helper method to check if array is sorted.
* @param array array to check
* @param lo low boundary
* @param hi high boundary
* @return true if sorted and false if not
*/
private static boolean isSorted(int[] array, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++) {
if (array[i] < array[i - 1]) {
return false;
}
}
return true;
}
}