Implementing Merge Sort with Java - java

I was trying to implement merge sort using java, but it's saying:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at HelloWorld.merge(HelloWorld.java:42)
at HelloWorld.sort(HelloWorld.java:30)
at HelloWorld.sort(HelloWorld.java:28)
at HelloWorld.sort(HelloWorld.java:29)
at HelloWorld.sort(HelloWorld.java:28)
at HelloWorld.main(HelloWorld.java:10)
So I tried to copy the original array into a helper array in the merge subroutine, I think it's the length I use for helper array messed everything up, isn't "r-l+1" the length of the helper array?
If I put 100 as the length of the helper array, the code would work, but obviously it's not going to work when the size of the original array gets larger.
Please help and thanks in advance.
public class HelloWorld{
public static void main(String []args){
HelloWorld ms = new HelloWorld();
int arr[] = new int[]{4,3,0,1,3,2,4,20,13,22,10};
ms.sort(arr, 0, arr.length - 1);
ms.printArr(arr);
}
void printArr(int arr[])
{
int n = arr.length;
for(int i = 0; i<n; i++){
System.out.print(" "+arr[i]);
}
}
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);
}
}
void merge(int arr[], int l, int m, int r)
{
//find out helper array length
int helper[] = new int[r-l+1];
// Your code here
for(int i=l; i<=r; i++){
helper[i] = arr[i];
}
int i = l;
int k = l;
int j = m+1;
while(i<=m && j<=r){
if(helper[i]<=helper[j]){
arr[k]=helper[i];
i++;
}else{
arr[k]=helper[j];
j++;
}
k++;
}
while(i<=m){
arr[k]=helper[i];
i++;
k++;
}
}
}

If I understand the way you're attempting to implement the MERGE subroutine for your merge sort algorithm correctly, you're copying the relevant portion of the array (from index l, inclusive, to index l, inclusive) into the helper array, then modifying the original array using the data copied into the helper array.
In this case, the helper array should indeed have length r-l+1. However, taking a look at your code for copying the original array portion into the helper array, you're not offsetting your indexes in the for loop. The correct way to do it would be:
int helper[] = new int[r-l+1];
for (int i = l; i <= r; i++){
helper[i-l] = arr[i];
}
Don't forget arrays are zero indexed!
I do however recommend moving on to more modern ways of copying arrays if you absolutely have to copy them. In this case, the most adapted in my opinion would be the system call System.arraycopy(arr, l, helper, 0, r-l+1). If you would like to read more about the different methods of copying an array (completely or partially) in Java, check this answer out.

You create an array with the size r - l + 1
int helper[] = new int[r-l+1];
The merge method will be executed with l = 3, m = 3, r = 4
So the array helper has a size of r - l + 1 = 2 = [0, 0]
Your for loop runs from l..r
for(int i=l; i<=r; i++){
helper[i] = arr[i];
}
And you try to set the value from arr[3] to helper[3] which is not possible because helper.length = 2
That's why the ArrayIndexOutOfBoundsException occurs! You can modfiy the access to the helper index to i - l
void merge(int arr[], int l, int m, int r) {
// find out helper array length
int helper[] = new int[r - l + 1];
// Your code here
System.arraycopy(arr, l, helper, 0, helper.length);
int i = l;
int k = l;
int j = m + 1;
while (i <= m && j <= r) {
if (helper[i - l] <= helper[j - l]) { // <---
arr[k] = helper[i - l]; // <---
i++;
} else {
arr[k] = helper[j - l]; // <---
j++;
}
k++;
}
while (i <= m) {
arr[k] = helper[i - l]; // <---
i++;
k++;
}
}

Related

Why do we use two different loop variables while sorting an array using merge sort?

I was learning to merge sort an integer array, when I noticed that while copying the sorted array elements to the original array, we need two separate loop variables to run simultaneously, while the values at those indices are copied to the original array. Here is the code for reference:
class MergeSort {
public static void sort(int arr[], int si, int ei, int mid) {
int merged[] = new int[ei - si + 1];
int index1 = si; // tracks the first array
int index2 = mid + 1; // tracks the second array
int i = 0;
while (index1 <= mid && index2 <= ei) {
if (arr[index1] <= arr[index2]) {
merged[i++] = arr[index1++];
} else {
merged[i++] = arr[index2++];
}
} // end of while
while (index1 <= mid) {
merged[i++] = arr[index1++];
}
while (index2 <= ei) {
merged[i++] = arr[index2++];
}
// to copy merged[] to arr[]
int j = si;
for (i = 0; i < merged.length; i++, j++) {
arr[j] = merged[i];
}
} // end sort()
public static void divide(int arr[], int si, int ei) {
// base case
if (si >= ei) {
return;
} // end of base case
int mid = si + (ei - si) / 2; // same as (ei-si)/2 but with less space complexity
divide(arr, si, mid);
divide(arr, mid + 1, ei);
sort(arr, si, ei, mid);
} // end of divide
public static void main(String args[]) {
int arr[] = { 1, 8, 0, 7, -4 };
int n = arr.length;
divide(arr, 0, n - 1);
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
} // end of for
} // end of main
} // end of class
Notice that while copying the values of the array merged[] to the array arr[], we are using two separate variables i and j. I did try using only one loop variable, which went like:
for (int i = 0; i < arr.length; i++) {
arr[i] = merged[i];
}
but received an incorrect output. If anyone knows why we need two separate variables for the operation, please let me know. Thank you :)
You could use a single variable in this final loop, but you must add the offset of the start of the slice in the destination array:
for (int i = 0; i < arr.length; i++) {
arr[si + i] = merged[i];
}

Quicksort doesn't run Java [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 4 years ago.
Im trying to make a Quicksort but it always showing up the Error ArrayIndexOutOfBoundsException.
public class Quicksort
{
void sort(int[] arr)
{
_quicksort(arr, 0, arr.length - 1);
}
private void _quicksort(int[] arr, int left, int right)
{
int pivot = (left + right)/2;
int l = left;
int r = right;
while (l <= r)
{
while (arr[l] < pivot)
{
l++;
}
while (arr[r] > pivot)
{
r--;
}
if(l <= r)
{
int temp = l;
l = r;
r = temp;
l++;
r++;
}
}
if(left < r)
{
_quicksort(arr, left, r);
}
if(l < right)
{
_quicksort(arr, l, right);
}
}
}
Does someone know why it doesnt run? It always gives a Error.
The Error message is
java.lang.ArrayIndexOutOfBoundsException: -1
at Quicksort._quicksort(Quicksort.java:18)
at Quicksort._quicksort(Quicksort.java:33)
at Quicksort.sort(Quicksort.java:5)
Error Message
It seems like there are a couple of issues with your code. I've listed them below:
The variable pivot stores the index of the pivot element and not the actual value. So, you can't use pivot for comaparison as you have done in the 2 nested while loops. You need arr[pivot] instead of pivot there.
Imagine arr looks like {1, 1, 1, 3, 2, 2, 2}. Here, pivot will be equal to 3 i.e. arr[pivot] will be equal to 3. Now, after both the nested while loops terminate, l will be equal to 3 and r will remain equal to 6. You then swap arr[l] and arr[r] and increment both l and r. Since l is still less than equal to r, the outer while loop runs for a second time and you'll get an ArrayIndexOutOfBoundsExecption when the control reaches the second nested while loop. This happens because you're trying to access arr[7] (Out of Bounds).
Here's my code:
class Quicksort
{
void sort(int[] arr)
{
myQuicksort(arr, 0, arr.length - 1);
}
private void myQuicksort(int[] arr, int l, int r) {
if (l >= r) {
return;
}
int pivotIndex = (l + r) / 2;
swap (arr, r, pivotIndex);
int pivotValue = arr[r];
int swapIndex = 0;
int currentIndex = 0;
while (currentIndex != r) {
if (arr[currentIndex] < pivotValue) {
swap(arr, currentIndex, swapIndex);
swapIndex++;
}
currentIndex++;
}
swap(arr, r, swapIndex);
myQuicksort(arr, l, swapIndex - 1);
myQuicksort(arr, swapIndex + 1, r);
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
public class Main{
public static void main(String[] args) {
Quicksort quicksort = new Quicksort();
int[] arr = {3, 7, 1, 0, 4};
quicksort.sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
}
You should read up on Quicksort. But here are the main points:
Choose a random pivot element and swap it with the last element. This makes the implementation much simpler.
Loop over the input array and keep a track of a swapIndex such that everything before the swapIndex is less than the pivotValue and everything from the swapIndex till the currentIndex is greater than (or equal) the pivotValue.
After the loop runs out, swap the element at swapIndex with the pivot. This inserts the pivot in its correct position.
The pivot divides the array into 2 subarrays. Call myQuicksort on these 2 subarrays.

merge sort is duplicatiing array entries

I was trying to implement in Java the merge sort algorithm according to Cormen's Introduction to Algorithms. The problem with my code (below) is that the main array is duplicating some of its entries during the merge step.
Is someone able to catch what I'm doing wrong?
Thank you!
static void merge(int a[], int p, int q, int r)
{
int n1 = q - p;
int n2 = (r - q);
int [] left = new int[n1 + 1];
int [] right = new int[n2 + 1];
int pp = p;
int qq = q;
for(int i = 0; i < n1; i++)
{
left[i] = a[++pp];
}
for(int i = 0; i < n2; i++)
{
right[i] = a[++qq];
}
left[left.length-1] = Integer.MAX_VALUE;
right[right.length-1] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
for(int k = p; k < r; k++)
{
if(left[i] <= right[j])
{
a[k] = left[i];
i++;
}
else
{
a[k] = right[j];
j++;
}
}
}
static int [] mergeSort(int a[], int p, int r)
{
if(p < r)
{
int q = (p + r)/2;
mergeSort(a, 1, q);
mergeSort(a, q + 1, r);
merge(a, p, q, r);
}
return a;
}
Part of the issue here is the example from the book apparently uses index range from 1 to length. It will be simpler if you change the index range from 0 to length-1, which I assume in the rest of my answer.
Use post increment while copying to left[] and right[] as answered by laune (since index range 0 to length-1).
left[i] = a[pp++];
...
right[i] = a[qq++];
The main issue is the merge function is not checking to see if it reached the end of the left or right run during a merge. This can be fixed by changing the inner if to:
if (i < n1 && (j >= n2 || left[i] <= right[j]))
The recursive calls to merge sort should be:
mergeSort(a, p, q);
mergeSort(a, q, r);
Not shown, but the initial call to mergeSort should be:
mergeSort(a, 0, a.length);
There's no need to allocate the extra element in left and right (since index range is 0 to length-1).
int [] left = new int[n1];
int [] right = new int[n2];
I think that this is in error (as well as its sibling in the next loop):
left[i] = a[++pp];
You want to copy starting with pp = p, so don't increment before you access the array element:
left[i] = a[pp++];

Is this a proper implementation of mergesort?

I'm worried that the creation of 3 arrays for every recursion step might take up too much space, but I really couldn't figure out another way of doing it. Please tell me whatever is wrong with it.
public static int[] split(int [] vector){
if(vector.length <= 1 || vector == null)
return vector;
int len = vector.length;
int[] list1 = new int[len / 2];
// If the number of elements is odd the second list will be bigger
int[] list2 = new int[len / 2 + (len % 2)];
// Here we assign the elements to 2 separate lists
for(int x = 0; x < len / 2; x++)
list1[x] = vector[x];
for(int j = 0, i = len / 2; j < list2.length; i++, j++)
list2[j]=vector[i];
// Apply the recursion, this will eventually order the lists
list1 = split(list1);
list2 = split(list2);
// Here we take the 2 ordered lists and merge them into 1
int i = 0, a = 0, b = 0;
int[] listfinal = new int[len];
while(i < len){
if(a >= list1.length){
listfinal[i] = list2[b];
b++;
} else if(b >= list2.length){
listfinal[i] = list1[a];
a++;
} else if(list1[a] <= list2[b]){
listfinal[i] = list1[a];
a++;
} else if(list1[a] > list2[b]){
listfinal[i] = list2[b];
b++;
}
i++;
}
return listfinal; // Return the merged and ordered list
}
You shouldn't need to create more than one temporary array to do mergesort. What you're doing wrong is copying the arrays to pass to the recursive invocation; you should instead pass the original array.
It may be informative to look at the implementation of mergesort in the JDK - look on line 1146 of Arrays.java.
Here is code that allocates a single array equal to the input size at the top level and re-uses it for all the recursion. On a million integers, this takes about 300 ms on my machine and the Java library sort takes 230 ms. Okay for no tuning effort, I guess...
// Sort the elements of a between lo and hi inclusive.
private static void sortImpl(int [] a, int lo, int hi, int [] tmp) {
if (hi <= lo) return;
// Recur on sublists.
int mid = (hi + lo) / 2;
sortImpl(a, lo, mid, tmp);
sortImpl(a, mid + 1, hi, tmp);
// Move past items already in the right place.
int t1 = lo;
while (a[t1] < a[mid + 1]) t1++;
// Merge sublists into result.
int p1 = t1;
int p2 = mid + 1;
int i = t1;
System.arraycopy(a, t1, tmp, t1, mid - t1 + 1);
while (p1 <= mid)
a[i++] = (p2 > hi || tmp[p1] < a[p2]) ? tmp[p1++] : a[p2++];
}
public static void sort(int [] a) {
sortImpl(a, 0, a.length - 1, new int[a.length]);
}

Merge Sort Java

I am trying to make a merge sort method, but it keeps on giving the wrong sorts. Where do I have change to make it actually sort the array? What part of the code has to be different? Thank you for your time.
public static void mergeSort(int[] array, int left, int lHigh, int right, int rHigh) {
int elements = (rHigh - lHigh +1) ;
int[] temp = new int[elements];
int num = left;
while ((left <= lHigh) && (right <= rHigh)){
if (a[left] <= array[right]) {
temp[num] = array[left];
left++;
}
else {
temp[num] = array[right];
right++;
}
num++;
}
while (left <= right){
temp[num] = array[left]; // I'm getting an exception here, and is it because of the num???
left += 1;
num += 1;
}
while (right <= rHigh) {
temp[num] = array[right];
right += 1;
num += 1;
}
for (int i=0; i < elements; i++){
array[rHigh] = temp[rHigh];
rHigh -= 1;
}
EDIT: now the mergeSort doesn't really sort the numbers, can someone tell me where it specifically is? especially when I print the "Testing merge sort" part.
First of all, I'm assuming this is academic rather than practical, since you're not using a built in sort function. That being said, here's some help to get you moving in the right direction:
Usually, one can think of a merge sort as two different methods: a merge() function that merges two sorted lists into one sorted list, and mergeSort() which recursively breaks the list into single element lists. Since a single element list is sorted already, you then merge all the lists together into one big sorted list.
Here's some off-hand pseudo-code:
merge(A, B):
C = empty list
While A and B are not empty:
If the first element of A is smaller than the first element of B:
Remove first element of A.
Add it to the end of C.
Otherwise:
Remove first element of B.
Add it to the end of C.
If A or B still contains elements, add them to the end of C.
mergeSort(A):
if length of A is 1:
return A
Split A into two lists, L and R.
Q = merge(mergeSort(L), mergeSort(R))
return Q
Maybe that'll help clear up where you want to go.
If not, there's always MergeSort at wikipedia.
Additional:
To help you out, here are some comments inline in your code.
public static void mergeSort(int[] array, int left, int lHigh, int right, int rHigh) {
// what do lHigh and rHigh represent?
int elements = (rHigh - lHigh +1) ;
int[] temp = new int[elements];
int num = left;
// what does this while loop do **conceptually**?
while ((left <= lHigh) && (right <= rHigh)){
if (a[left] <= a[right]) {
// where is 'pos' declared or defined?
temp[pos] = a[left];
// where is leftLow declared or defined? Did you mean 'left' instead?
leftLow ++;
}
else {
temp[num] = a[right];
right ++;
}
num++;
}
// what does this while loop do **conceptually**?
while (left <= right){
// At this point, what is the value of 'num'?
temp[num] = a[left];
left += 1;
num += 1;
}
while (right <= rHigh) {
temp[num] = a[right];
right += 1;
num += 1;
}
// Maybe you meant a[i] = temp[i]?
for (int i=0; i < elements; i++){
// what happens if rHigh is less than elements at this point? Could
// rHigh ever become negative? This would be a runtime error if it did
a[rHigh] = temp[rHigh];
rHigh -= 1;
}
I'm purposefully being vague so you think about the algorithm. Try inserting your own comments into the code. If you can write what is conceptually happening, then you may not need Stack Overflow :)
My thoughts here are that you are not implementing this correctly. This is because it looks like you're only touching the elements of the array only once (or close to only once). This means you have a worst case scenario of O(N) Sorting generally takes at least O(N * log N) and from what I know, the simpler versions of merge sort are actually O(N^2).
More:
In the most simplistic implementation of merge sort, I would expect to see some sort of recursion in the mergeSort() method. This is because merge sort is generally defined recursively. There are ways to do this iteratively using for and while loops, but I definitely don't recommend it as a learning tool until you get it recursively.
Honestly, I suggest taking either my pseudo-code or the pseudo-code you may find in a wikipedia article to implement this and start over with your code. If you do that and it doesn't work correctly still, post it here and we'll help you work out the kinks.
Cheers!
And finally:
// Precondition: array[left..lHigh] is sorted and array[right...rHigh] is sorted.
// Postcondition: array[left..rHigh] contains the same elements of the above parts, sorted.
public static void mergeSort(int[] array, int left, int lHigh, int right, int rHigh) {
// temp[] needs to be as large as the number of elements you're sorting (not half!)
//int elements = (rHigh - lHigh +1) ;
int elements = rHigh - left;
int[] temp = new int[elements];
// this is your index into the temp array
int num = left;
// now you need to create indices into your two lists
int iL = left;
int iR = right;
// Pseudo code... when you code this, make use of iR, iL, and num!
while( temp is not full ) {
if( left side is all used up ) {
copy rest of right side in.
make sure that at the end of this temp is full so the
while loop quits.
}
else if ( right side is all used up) {
copy rest of left side in.
make sure that at the end of this temp is full so the
while loop quits.
}
else if (array[iL] < array[iR]) { ... }
else if (array[iL] >= array[iR]) { ... }
}
}
public class MergeSort {
public static void main(String[] args) {
int[] arr = {5, 4, 7, 2, 3, 1, 6, 2};
print(arr);
new MergeSort().sort(arr, 0, arr.length - 1);
}
private void sort(int[] arr, int lo, int hi) {
if (lo < hi) {
int mid = (lo + hi) / 2;
sort(arr, lo, mid); // recursive call to divide the sub-list
sort(arr, mid + 1, hi); // recursive call to divide the sub-list
merge(arr, lo, mid, hi); // merge the sorted sub-lists.
print(arr);
}
}
private void merge(int[] arr, int lo, int mid, int hi) {
// allocate enough space so that the extra 'sentinel' value
// can be added. Each of the 'left' and 'right' sub-lists are pre-sorted.
// This function only merges them into a sorted list.
int[] left = new int[(mid - lo) + 2];
int[] right = new int[hi - mid + 1];
// create the left and right sub-list for merging into original list.
System.arraycopy(arr, lo, left, 0, left.length - 1);
System.arraycopy(arr, mid + 1, right, 0, left.length - 1);
// giving a sentinal value to marking the end of the sub-list.
// Note: The list to be sorted is assumed to contain numbers less than 100.
left[left.length - 1] = 100;
right[right.length - 1] = 100;
int i = 0;
int j = 0;
// loop to merge the sorted sequence from the 2 sub-lists(left and right)
// into the main list.
for (; lo <= hi; lo++) {
if (left[i] <= right[j]) {
arr[lo] = left[i];
i++;
} else {
arr[lo] = right[j];
j++;
}
}
}
// print the array to console.
private static void print(int[] arr) {
System.out.println();
for (int i : arr) {
System.out.print(i + ", ");
}
}
}
Here's another!
private static int[] mergeSort(int[] input){
if (input.length == 1)
return input;
int length = input.length/2;
int[] left = new int[length];
int[] right = new int[input.length - length];
for (int i = 0; i < length; i++)
left[i] = input[i];
for (int i = length; i < input.length; i++)
right[i-length] = input[i];
return merge(mergeSort(left),mergeSort(right));
}
private static int[] merge(int[] left, int[] right){
int[] merged = new int[left.length+right.length];
int lengthLeft = left.length;
int lengthRight = right.length;
while (lengthLeft > 0 && lengthRight > 0){
if (left[left.length - lengthLeft] < right[right.length - lengthRight]){
merged[merged.length -lengthLeft-lengthRight] = left[left.length - lengthLeft];
lengthLeft--;
}else{
merged[merged.length - lengthLeft-lengthRight] = right[right.length - lengthRight];
lengthRight--;
}
}
while (lengthLeft > 0){
merged[merged.length - lengthLeft] = left[left.length-lengthLeft];
lengthLeft--;
}
while (lengthRight > 0){
merged[merged.length - lengthRight] = right[right.length-lengthRight];
lengthRight--;
}
return merged;
}
static void mergeSort(int arr[],int p, int r) {
if(p<r) {
System.out.println("Pass "+k++);
int q = (p+r)/2;
mergeSort(arr,p,q);
mergeSort(arr,q+1,r);
//System.out.println(p+" "+q+" "+r);
merge(arr,p,q,r);
}
}
static void merge(int arr[],int p,int q,int r) {
int temp1[],temp2[];
//lower limit array
temp1 = new int[q-p+1];
//upper limit array
temp2 = new int[r-q];
for(int i=0 ; i< (q-p+1); i++){
temp1[i] = arr[p+i];
}
for(int j=0; j< (r-q); j++){
temp2[j] = arr[q+j+1];
}
int i = 0,j=0;
for(int k=p;k<=r;k++){
// This logic eliminates the so called sentinel card logic mentioned in Coreman
if(i!= temp1.length
&& (j==temp2.length || temp1[i] < temp2[j])
) {
arr[k] = temp1[i];
// System.out.println(temp1[i]);
i++;
}
else {
//System.out.println(temp2[j]);
arr[k] = temp2[j];
j++;
}
}
}
>
Merge Sort Using Sentinel
This codes works perfectly fine.
public void mergeSort(int a[], int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
mergeSort(a, low, mid);
mergeSort(a, mid + 1, high);
merge(a, low, mid, high);
}
}
public void merge(int a[], int low, int mid, int high) {
int n1 = mid - low + 1;// length of an array a1
int n2 = high - mid; // length of an array a2
int a1[] = new int[n1 + 1];
int a2[] = new int[n2 + 1];
int lowRange = low;
for (int i = 0; i < n1; i++) {
a1[i] = a[lowRange];
lowRange++;
}
for (int j = 0; j < n2; j++) {
a2[j] = a[mid + j + 1];
}
a1[n1] = Integer.MAX_VALUE; // inserting sentinel at the end of array a1
a2[n2] = Integer.MAX_VALUE; // inserting sentinel at the end of array a2
int i = 0;
int j = 0;
int k = low;
for (k = low; k <= high; k++) {
if (a1[i] >= a2[j]) {
a[k] = a2[j];
j++;
} else {
a[k] = a1[i];
i++;
}
}
if (a2.length >= a1.length) {
for (int ab = k; ab < a2.length; ab++) {
a[k] = a2[ab];
k++;
}
} else if (a1.length >= a2.length) {
for (int ab = k; ab < a1.length; ab++) {
a[k] = a1[ab];
k++;
}
}
}
Here's another alternative:
public class MergeSort {
public static void merge(int[]a,int[] aux, int f, int m, int l) {
for (int k = f; k <= l; k++) {
aux[k] = a[k];
}
int i = f, j = m+1;
for (int k = f; k <= l; k++) {
if(i>m) a[k]=aux[j++];
else if (j>l) a[k]=aux[i++];
else if(aux[j] > aux[i]) a[k]=aux[j++];
else a[k]=aux[i++];
}
}
public static void sort(int[]a,int[] aux, int f, int l) {
if (l<=f) return;
int m = f + (l-f)/2;
sort(a, aux, f, m);
sort(a, aux, m+1, l);
merge(a, aux, f, m, l);
}
public static int[] sort(int[]a) {
int[] aux = new int[a.length];
sort(a, aux, 0, a.length-1);
return a;
}
}
Here is a simple merge sort algorithm in Java:
Good Tip: Always use int middle = low + (high-low)/2 instead of int middle = (low + high)/2.
public static int[] mergesort(int[] arr) {
int lowindex = 0;
int highindex = arr.length-1;
mergesort(arr, lowindex, highindex);
return arr;
}
private static void mergesort(int[] arr, int low, int high) {
if (low == high) {
return;
} else {
int midIndex = low + (high-low)/2;
mergesort(arr, low, midIndex);
mergesort(arr, midIndex + 1, high);
merge(arr, low, midIndex, high);
}
}
private static void merge(int[] arr, int low, int mid, int high) {
int[] left = new int[mid-low+2];
for (int i = low; i <= mid; i++) {
left[i-low] = arr[i];
}
left[mid-low+1] = Integer.MAX_VALUE;
int[] right = new int[high-mid+1];
for (int i = mid+1; i <= high; i++) {
right[i-mid-1] = arr[i];
}
right[high - mid] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
for (int k = low; k <= high; k++) {
if (left[i] <= right[j]) {
arr[k] = left[i];
i++;
} else {
arr[k] = right[j];
j++;
}
}
}
package com.sortalgo;
import java.util.Arrays;
public class MyMSort {
private static void merge(int[] array, int[] result, int low, int mid, int high) {
int k =low, i=low; int j=mid+1;
while(i<=mid && j<=high) {
if(array[i]<= array[j]) {
result[k++]=array[i++];
}else {
result[k++]=array[j++];
}
}
while(i<=mid) {
result[k++]=array[i++];
}
while(j<=high) {
result[k++]=array[j++];
}
for(i=low;i<=high;i++) {
array[i]=result[i];
}
}
private static void mergeSort(int[] array, int[] result, int low, int high) {
if(high == low) {
return ;
}
int mid = (low + high)/2;
mergeSort(array,result, low, mid );
mergeSort(array,result, mid+1, high );
merge(array, result, low, mid, high);
}
public static void main(String[] args) {
int[] array = {8,4,3,12,25,6,13,10};
int[] result = new int[array.length];
mergeSort(array, result, 0, array.length-1 );
for(int i=0; i<=array.length-1;i++) {
System.out.println(array[i]);
}
}
}

Categories

Resources