I have created an implementation of radixsort using ArrayLists of integer arrays. The code is functional however as input size increases passed about 100,000 execution time is far too high. I need this code to be able to handle an input of 1,000,000 integers. What can I do to optimize execution time?
public class RadixSort {
public static void main(String[] args) {
// generate and store 1,000,000 random numbers
int[] nums = generateNums(1000000);
// sort the random numbers
int[] sortedNums = radixSort(nums);
// check that the array was correctly sorted and print result
boolean sorted = isSorted(sortedNums);
if (sorted) {
System.out.println("Integer list is sorted");
} else {
System.out.println("Integer list is NOT sorted");
}
}
/**
* This method generates numCount random numbers and stores them in an integer
* array. Note: For our program, numCount will always equal 1,000,000.
*
* #return nums the new integer array
*/
public static int[] generateNums(int numCount) {
// create integer array with length specified by the user
int[] nums = new int[numCount];
int max = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
nums[i] = (int) (Math.random() * max + 1);
}
// return new integer array
return nums;
}
/**
* This method implements a radix sort
*
* #param nums
* the integer array to sort
* #return nums the sorted integer array
*/
public static int[] radixSort(int[] nums) {
// find max number of digits in an element in the array
int maxDigits = findMaxDigits(nums);
// specified decimal place
int digit = 1;
// create 10 buckets
ArrayList<Integer>[] buckets = new ArrayList[10];
// iterate through the list for as many times as necessary (maxDigits)
for (int j = 0; j < maxDigits; j++) {
// initialize buckets as ArrayLists
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new ArrayList<Integer>();
}
// isolate digit at specified decimal place and add the number to the
// appropriate bucket
for (int i = 0; i < nums.length; i++) {
int last = (nums[i] / digit) % 10;
buckets[last].add(nums[i]);
// convert buckets to an integer array
nums = convertToIntArray(buckets, nums);
}
// update digit to find next decimal place
digit *= 10;
}
// return sorted integer array
return nums;
}
/**
* This method converts from an ArrayList of integer arrays to an integer array
*
* #param buckets
* the ArrayList of integer arrays
* #param nums
* the integer array to return
* #return nums the new integer array
*/
public static int[] convertToIntArray(ArrayList<Integer>[] buckets, int[] nums) {
// loop through the ArrayList and put elements in order into an integer array
int i = 0;
for (ArrayList<Integer> array : buckets) {
if (array != null) {
for (Integer num : array) {
nums[i] = num;
i++;
}
}
}
// return new integer array
return nums;
}
/**
* Method to find the max number of digits in a number in an integer array
*
* #param nums
* the integer array to search through
* #return maxLength the max number of digits in a number in the integer array
*/
public static int findMaxDigits(int[] nums) {
// find maximum number
int max = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
// find and return the number of digits in the maximum number
int maxLength = String.valueOf(max).length();
return maxLength;
}
/**
* This method is used for testing correct functionality of the above radixSort
* method.
*
* #param nums
* the integer array to check for correct sorting
* #return false if the array is sorted incorrectly, else return true.
*/
public static boolean isSorted(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
return false;
}
}
return true;
}
}
Related
I am trying to implement bi-directional selection sort(double selection sort).
A double-selection sort finds both the smallest and largest elements during its scan, and swaps the smallest into the first position, and the largest into the last position. The algorithm then proceeds looking at all the elements between the first and last.
I am able to get the logic required to perform the task.But,i think i am doing something wrong with comparing variables or maybe implementing comparable properly.
public void sort(T[] input) {
for(int i=0; i<input.length -1; i++){
int min = i;
int max = i;
for(int j=i+1; j<input.length; j++){
if(input[min].compareTo((input[j])) > 0 )
{
min = j;
T swap = input[min];
input[min] = input[i];
input[i] = swap;
}
}
for(int k=i+1; k<input.length; k++){
if(input[max].compareTo((input[k])) < 0 )
{
max = k;
T swap = input[max];
input[max] = input[i];
input[i] = swap;
}
}
}
}
///// Test File
/** Returns true if the input array is ordered (every element ≤
* the following one.)
*
* #param data Array to check
* #return True if array is ordered
*/
boolean isOrdered(Integer[] data) {
for(int i = 0; i < data.length - 1; ++i)
if(data[i] > data[i+1])
return false;
return true;
}
/** Counts the number of times x occurs in the array in.
*
* #param in Array
* #param x Element to count
* #return Count of x's in the array
*/
int countElement(Integer[] in, Integer x) {
int c = 0;
for(int i : in)
if(i == x)
c++;
return c;
}
/** Returns true if both arrays contain the same elements,
* disregarding order (i.e., is one a permutation of the other).
* #param in Unsorted array
* #param out Potentially-sorted array to check
* #return True if out is a permutation of in
*/
boolean sameElements(Integer[] in, Integer[] out) {
for(Integer i : in)
if(countElement(in,i) != countElement(out,i))
return false;
return true;
}
/** Creates an array of the given size filled with random values.
*
* #param size Size of the resulting array
* #return Array of random values
*/
Integer[] randomArray(int size) {
Integer[] arr = new Integer[size];
for(int i = 0; i < size; ++i)
arr[i] = Math.round((float)Math.random() * Integer.MAX_VALUE);
return arr;
}
/** Tests the DoubleSelectionSort dss against the unsorted data.
*
* #param dss Sorter to use
* #param data Array to sort and check
*/
void testSort(DoubleSelectionSort dss, Integer[] data) {
Integer[] sorted = Arrays.copyOf(data, data.length);
dss.sort(sorted);
assertTrue("Result of sort is not sorted in order", isOrdered(sorted));
assertTrue("Result of sort has different elements from input", sameElements(data, sorted));
}
#Test
public void testSort() {
System.out.println("sort");
DoubleSelectionSort<Integer> dss = new DoubleSelectionSort<>();
// Test on arrays size 0 to 100
for(int i = 0; i <= 100; ++i)
testSort(dss, randomArray(i));
}
}
testSort Failed : Result of Sort is not sorted in order
It seems that you are using wrong conditions in Sorting Logic of Selection Sort.
I have given here example of Selection Sort function with generic type. Please have a look at this:
public static <E extends Comparable<E>> void selectionSort(E[] list)
{
for(int i=0; i<list.length -1; i++)
{
int iSmall = i;
for(int j=i+1; j<list.length; j++)
{
if(list[iSmall].compareTo((list[j])) > 0 )
{
iSmall = j;
}
}
E iSwap = list[iSmall];
list[iSmall] = list[i];
list[i] = iSwap;
}
}
I am trying to create 3 methods which calculate the sum and average of a random array then outputting the result.
I am trying to get an output similar to -
java RandomArray 5
9 7 2 1 4
Sum: 23
Mean: 4.6
but I am getting "Usage: java RandomArray . Example: java RandomArray 5"
if you can spot the errors in my code and help with how to get this output.
public class RandomArray {
private int[] numbers; //instance variable
/**
* Constructor
*
*#param size The size of the array
*/
public RandomArray(int size){
numbers = new int[size];
for(int i=0; i<numbers.length;i++){
numbers[i] = (int)(Math.random()*10); // a random number between 0-9
}
}
/**
* a method to print the array elements
*/
public void printArray() {
for (int i = 0; i < numbers.length; i++)
System.out.print(i + " ");
}
/**
* A method to calculate the sum of all elements
*
*#return The sum
*/
public int calSum(){
int sum = 0;
for (int value : numbers) {
sum += value;
}
return sum;
}
/**
* A method to calculate the mean of all elements
*
*#return The mean
*/
public double calMean() {
int sum = calSum();
int length = numbers.length;
return (double) sum / length;
}
/**
* a method to print the array elements in reverse order
*/
public void printReverse(){
}
/**
* A main method to test
*/
public static void main(String[] args) {
// Check to see if the user has actually sent a paramter to the method
if (args.length != 1){
System.out.println("Usage: java RandomArray <NUM>. Example: java RandomArray 5");
System.exit(-1);
}
// Create an instance of the class
RandomArray test = new RandomArray(Integer.parseInt(args[0]));
// Print the array
test.printArray();
// Calculate the sum of all the values in the array and print it
System.out.println("Sum: "+ test.calSum());
// Calculate the mean of all the values in the array and print it
System.out.println("Mean: "+ test.calMean());
System.out.print("Reverse: ");
test.printReverse();
}
}
Let’s look at your sum method first:
public int calSum(int sum) {
int sum = 0;
for (int value : numbers) {
sum += value;
}
return sum;
}
Why does this method accept a parameter? You just redeclare it on the next line anyway.
Looks good otherwise.
Here’s a cleaned up version:
public int calSum() {
int sum = 0;
for (int value : numbers) {
sum += value;
}
return sum;
}
Next up, mean average:
public double calMean(int[] array){
//Unsure which elements go here
}
Again, why the parameter?
Recall how we calculate the mean average: sum all elements, then divide by the number of elements.
We’ve already got a method for calculating the sum, so we can use that.
public double calMean() {
int sum = calSum();
int length = numbers.length;
return (double) sum / length;
}
Note the use of (double) here. Without it, cal / length would be integer division, and the result would be rounded to the nearest whole number.
Your method "printArray(int sum)" has the mistake. When you call the method you take a parameter sum, which is not needed. Then you try to create a second local variable with the name sum. This is impossible, because you already have a parameter called sum.
In your for loop you init antoher local variable called sum. You need a different name for that variable, since you only need it for counting the loop.
So remove your parameter sum and rename the variable used in the for loop.
This should work:
import java.util.Arrays;
public class ArrayCalculations
{
private int[] numbers;
public ArrayCalculations(int size)
{
this.numbers = new int[size];
for (int i = 0; i < size; i++)
{
int randomNumber = (int) (Math.random() * 10);
numbers[i] = randomNumber;
}
}
public int calculateSum()
{
int sum = 0;
for (int i = 0; i < numbers.length; i++)
{
sum += numbers[i];
}
return sum;
}
public float calculateAverage()
{
float sum = (float) calculateSum();
return sum / numbers.length;
}
public void printArray()
{
System.out.println(Arrays.toString(numbers));
}
public static void main(String[] args)
{
ArrayCalculations ac = new ArrayCalculations(5); // initiates an array with 5 elements
ac.printArray(); // prints the array to console
System.out.println("The sum is: " + ac.calculateSum()); // prints the sum
System.out.println("The average is: " + ac.calculateAverage()); // prints the average
}
}
I am trying to make radix sort function that calculates the number of digits of integer numbers using the radix sort as a base, and then sort the numbers from least significant to most significant.
I am using an array that holds random integers.
How can I make this method works well?
I am using this code:
public static void sort( int[] a, int radix)
{
int i, m = a[0], exp = 1, n = a.length;
int[] b = new int[10];
for (i = 1; i < n; i++)
if (a[i] > m)
m = a[i];
while (m / exp > 0)
{
int[] bucket = new int[10];
for (i = 0; i < n; i++)
bucket[(a[i] / exp) % 10]++;
for (i = 1; i < 10; i++)
bucket[i] += bucket[i - 1];
for (i = n - 1; i >= 0; i--)
b[--bucket[(a[i] / exp) % 10]] = a[i];
for (i = 0; i < n; i++)
a[i] = b[i];
exp *= 10;
}
}
Try
int[] b = new int[a.length];
or since n = a.length
int[] b = new int[n];
I am just pointing out the most obvious problems and leave the details to you.
Each bucket will have to hold a list of numbers so using just an int as a bucket is not going to work. Use something like this instead:
List<Integer>[] bucket = new List<Integer>[10];
The array used to collect the elements in the new order needs to be the same size as the original array. You just have made it 10 long.
Statement in last for loop
a[i] = b[i];
tells that size of b must be equal to or greater than a. Hence go for #rcgldr answer. Also the value of radix passed to your function is lying unused. You can also make your function a tad faster by swapping array pointers instead of copying the elements i.e. avoiding the last for loop.
int swap[] = a;
a = b;
b = swap;
then finally after all the loops are over, return the array a
return a;
Above is your program for sorting in ascending order. I am giving below the program to sort in descending order. The only change that was required was to start adding frequencies from the end of the base array( in this case Z ) to index zero.
public static int[] DSC(int A[], int radix, int base)
{
int length = A.length ;
int B[] = new int[length] ;
int div = 1 ;
int swap[] ;
int i ;
while(radix > 0)
{
int Z[] = new int[base] ;
i = 0 ;
while(i < length)
{
Z[( A[i] / div ) % base]++ ;
i++ ;
}
i = base ;
while(i > 1)
{
i--;
Z[i-1] += Z[i] ;
}
i = length ;
while(i > 0)
{
i-- ;
B[--Z[( A[i] / div ) % base]] = A[i];
}
swap = A;
A = B;
B = swap;
div *= base;
radix--;
}
return A;
}
For non-negative integers, using binary instead of decimal, might be more efficient & intuitive for machine.
Here is an implementation I wrote, with test case:
RadixSort.java
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* Radix sort.
*
* #author eric
* #date 3/12/20 12:05 PM
*/
public class RadixSort {
/**
* Sort given array, the array will be modified.
*
* #param data array of integer of non-negative integers,
* #throws IllegalArgumentException if input contain negative integer,
*/
public static void sort(int[] data) {
int numSys = 2;
int bits = validAndfindHighestBit(data); // find highest bit,
// create queues,
List<List<Integer>> queues = new ArrayList<>(numSys);
for (int i = 0; i < numSys; i++) queues.add(new LinkedList<>());
// sort bit by bit, low to high,
for (int i = 0; i < bits; i++) {
// re-init queues,
for (int j = 0; j < numSys; j++) queues.get(j).clear();
// array -> queues,
for (int x : data) {
int bit = (x >> i) & 1; // get the i-th bit,
queues.get(bit).add(x);
}
// queues -> array,
int t = 0;
for (List<Integer> queue : queues) {
for (int x : queue) data[t++] = x;
}
}
}
/**
* Valid input number, and find highest bit that has 1.
*
* #param data
* #return
* #throws IllegalArgumentException if input contain negative integer,
*/
private static int validAndfindHighestBit(int[] data) {
// find max number,
int max = 0;
for (int x : data) {
if (x < 0) throw new IllegalArgumentException("negative integers are not supported");
if (x > max) max = x;
}
System.out.printf("max number: %d, ", max);
// find highest bit,
int highestBit = 0;
while (max != 0) {
highestBit++;
max >>= 1;
}
System.out.printf("highest bit: %d\n", highestBit);
return highestBit;
}
}
RadixSortTest.java
(Test case via TestNG)
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import static org.testng.Assert.*;
/**
* RadixSort test.
*/
public class RadixSortTest {
#Test
public void testSort() {
int[] data;
// generated un-sorted random array,
do data = genRandomArr(); while (data.length > 1 && isSorted(data));
System.out.printf("input arr:\t%s\n", Arrays.toString(data));
if (data.length > 1) Assert.assertFalse(isSorted(data));
// sort
RadixSort.sort(data);
System.out.printf("output arr:\t%s\n", Arrays.toString(data));
Assert.assertTrue(isSorted(data));
}
// corner case,
#Test
public void testSort_corner() {
int[] dataEmpty = new int[0]; // empty array,
RadixSort.sort(dataEmpty);
Assert.assertTrue(isSorted(dataEmpty));
int[] dataSingle = new int[]{5}; // single element,
RadixSort.sort(dataSingle);
Assert.assertTrue(isSorted(dataSingle));
}
// invalid input,
#Test(expectedExceptions = IllegalArgumentException.class)
public void testSort_invalid() {
int[] dataSingle = new int[]{1, -1}; // negative number,
RadixSort.sort(dataSingle);
}
/**
* generate random array, of size 10, in range [0, 1024),
*
* #return
*/
public static int[] genRandomArr() {
return genRandomArr(10, 100);
}
/**
* generate random array,
*
* #param size array size, default to 10,
* #param bound upper bound, default to 100,
* #return
*/
public static int[] genRandomArr(int size, int bound) {
if (size <= 0) size = 10;
if (bound <= 0) bound = 100;
ThreadLocalRandom rd = ThreadLocalRandom.current();
int[] arr = new int[size];
for (int i = 0; i < arr.length; i++) arr[i] = rd.nextInt(bound);
return arr;
}
// check whether array is sorted,
private static boolean isSorted(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) return false;
}
return true;
}
}
This method due to restrictions can not use ArrayLists. The method accepts an array, the desired value to find, and then the certain number of near values. It uses integers and integer arrays only. This is what I have so far
/**
* Return the k elements of a nearest to val.
* The array a is not changed as a result of calling this method.
* This method throws an IllegalArgumentException if k is negative.
* This method returns an array of zero length if k == 0 or if
* k > a.length.
*
* #param a the array to be searched
* #param val the reference value
* #param k the number of near elements to identify
* #return the k elements a[i] such that ABS(a[i] - val)
* are the k smallest evaluations
*
*/
public static int[] nearestK(int[] a, int val, int k) {
int x = 0;
int[] answer = new int[k];
if (k < x || a.length == 0 || a == null)
{
throw new IllegalArgumentException();
}
if (k == 0 || k > a.length)
{
int[] badAnswer = new int[0];
return badAnswer;
}
int[] copy = Arrays.copyOf(a, a.length);
Arrays.sort(copy);
int nearest = copy[0];
for (int i = 0; (i < copy.length); i++) {
if (Math.abs(nearest - val) > Math.abs(copy[i] - val)) {
nearest = copy[i]; x = i;
}
}
int index = 0;
while (index < answer.length) {
answer[index] = nearest;
nearest = copy[x + (index + 1)];
index++;
}
return answer;
}
This method works sometimes but i began to realize that it only used values after the desired element.
i.e
int[1,3,5,7,10,11,12} this method, if searched for 6, with 3 nearest values, would only return
7,10,11 as an array. This clearly is not correct. I am very new to java so at this point I am wondering what are some alternatives to this or ways of correcting this method.
Here's a clever answer: Instead of sorting the array in natural order, sort it according to the distance to val. Then, all you need to do is pick the first k elements:
public static int[] nearestK(int[] a, int val, int k) {
// omitted your checks for brevity
final int value = val; // needs to be final for the comparator, you can also make the parameter final and skip this line
Integer[] copy = new Integer[a.length]; // copy the array using autoboxing
for (int i = 0; i < a.length; i++) {
copy[i] = a[i];
}
Arrays.sort(copy, new Comparator<Integer>() { // sort it with a custom comparator
#Override
public int compare(Integer o1, Integer o2) {
int distance1 = Math.abs(value - o1);
int distance2 = Math.abs(value - o2);
return Integer.compare(distance1, distance2);
}
});
int[] answer = new int[k]; // pick the first k elements
for (int i = 0; i < answer.length; i++) {
answer[i] = copy[i];
}
return answer;
}
I have this code that sorts an array that is filled with random numbers and counts the number comparisons that it takes to complete the sort. I'm using the sort methods selection bubble and merge sort. I have the counter for the selection and the bubble but not the merge I have no clue where to put it. It might be a simple answer but I just can't get it to work.
Code:
/***********************************************************************
*
* Selection Sort:
* Reads in the array and then searches for the largest number.
* After it finds the largest number, it then swaps that number with the
* last number of the array
* Precondition: takes in an array of "n" items, which in this particular
* case is 2000, 4000, 6000, 8000, and 10000 random items in an array
* Postcondition: all numbers are sorted in ascending order
*
**********************************************************************/
public static int SelectionSort (int[] intArray) {
//Set initial count of comparisons at 0
comparisons= 0; //Number of swaps made
for(int last = intArray.length - 1; last > 0; last--) {
int largestIndex = last; //Int which places the largest number at the end of the array
// Find largest number
for(int i = 0; i < last; i++) {
//if i > the last number
if (intArray[i] > intArray[largestIndex]){
largestIndex = i; //switch the last number and i
} // end if
//Comparison+1
comparisons++;
} // end for
// Swap last element with largest element
int largest = intArray[last];
intArray[last] = intArray[largestIndex];
intArray[largestIndex] = largest;
}
//Return comparison counter
return comparisons;
}
/***********************************************************************
*
* Bubble Sort:
* Takes an array of random integers and sorts them by comparing adjacent
* numbers to one another. Whichever the larger adjacent number, Bubble
* Sort switches it towards the back end of the adjacent numbers. It does
* this until the list is fully sorted.
* Precondition: takes in a random array of integers
* Postcondition: array is sorted from smallest to largest
*
**********************************************************************/
public static int BubbleSort (int[] intArray) {
//Instance Variables
int n = intArray.length;
//boolean swap;
comparisons = 0;
//swap = false;
//for i starts at 0, when i is less than array length, i++ until reach array length
for(int i=0; i < n; i++) {
for(int j=1; j < (n-i); j++) {
if(intArray[j-1] > intArray[j]) {
//Swap the elements
int temp = intArray[j];
intArray[j] = intArray[j+1];
intArray[j+1] = temp;
//swap = true;
}
//comparisons get +1 until the for loop is done sorting
comparisons++;
} //End for loop
}
//Return the comparison counter
return comparisons;
}
/************************************************************************************
*
* Merge Sort:
* This method takes a random array and splits it in half. Once the array is
* split in half, it creates a temp0rary array. This temporary array is built by
* the method searching the two halves of the original array and puts the information
* in order stored in the temporary array. Once all the numbers are in order, the
* temporary array is then copied back to the original array.
* Precondition: take in an array of random integers
* Postcondition: return the random array sorted in ascending order
*
**********************************************************************************/
public static int mergeSort(int[] intArray) {
if(intArray.length >= 2) {
int mid = intArray.length / 2;
//Create 2 arrays to store half of the data in each
int[] first = new int[mid]; //holds first half of array
int[] second = new int[intArray.length - mid]; //holds second half of array
for(int i = 0; i < first.length; i++) {
first[i] = intArray[i];
}
for(int i = 0; i < second.length; i++) {
second[i] = intArray[mid+i];
}
mergeSort(first);
mergeSort(second);
merge(first, second, intArray); //Merge all together
}
return comparisons;
}
//merging first and second halves of mergeSort array
public static int merge(int[] first, int[] second, int[] intArray) {
int iFirst = 0;
int iSecond = 0;
int i = 0;
//moving the smaller element into intArray
while(iFirst < first.length && iSecond < second.length) {
comparisons++;
if(first[iFirst] < second[iSecond]) {
intArray[i] = first[iFirst];
iFirst++;
}
else {
intArray[i] = second[iSecond];
iSecond++;
}
i++;
}
//copying the remaining of first array
while(iFirst < first.length) {
intArray[i] = first[iFirst];
iFirst++; i++;
}
//copying the remaining of second array
while(iSecond < second.length)
{
intArray[i] = second[iSecond];
iSecond++; i++;
}
return comparisons;
}
/**************************************************************************************
* Instance methods:
* These methods perform actions to the array.
*
* copyArray()--makes a copy of the array to be used in the main class
* so that each method is able to create the same array
*
* printArray()--prints out the array for display
*
* randomArray()--creates a random integer array used by all three sorting methods
*
**************************************************************************************/
public static int[] copyArray(int[] intArray) {
//Constructor that creates copyArray
int[] copyArray = new int[intArray.length]; //siz equal to the length of the array
for(int i = 0; i < intArray.length; i++){
copyArray[i] = intArray[i];
} // end for
return copyArray;
} // end copyArray
//Prints out array
public static void printArray(int[] intArray){
//Preconditions
// Input: unsorted integer array
// Assumptions: array is full
//Postconditions
// Output: none
// Actions: array is displayed on screen
System.out.print("Array==> ");
for(int i = 0; i < intArray.length; i++){
System.out.print(intArray[i] + " ");
} // end for
System.out.println(" ");
} // end printArray
//Creates a random array that is used for each sorting method
public static int[] randomArray(int array, double range){
//Preconditions
// Input: size of array(n), range of integers (0 to range)
// Assumptions: none
//Postconditions
// Output: array of random integers 0 to floor(range)
// Actions: none
int[] intArray = new int[array];
for(int i = 0; i < array; i++){
intArray[i] = (int)(Math.random() * range);
} // end for
return intArray;
} // end randomIntArray
}
When (or just prior to) the following lines are executed:
if (intArray[i] > intArray[largestIndex]){
if(intArray[j-1] > intArray[j]) {
if(first[iFirst] < second[iSecond]) {
Your mergeSort method uses recursion. As such, it needs to take a comparisons parameter, and pass that down to each subsequent method call and receive the resulting value back again.
public static int mergeSort(int[] intArray, int comparisons) {
if(intArray.length >= 2) {
int mid = intArray.length / 2;
//Create 2 arrays to store half of the data in each
int[] first = new int[mid]; //holds first half of array
int[] second = new int[intArray.length - mid]; //holds second half of array
for(int i = 0; i < first.length; i++) {
first[i] = intArray[i];
}
for(int i = 0; i < second.length; i++) {
second[i] = intArray[mid+i];
}
comparisons = mergeSort(first, comparisons);
comparisons = mergeSort(second, comparisons);
comparisons = merge(first, second, intArray, comparisons); //Merge all together
}
return comparisons;
}
//merging first and second halves of mergeSort array
public static int merge(int[] first, int[] second, int[] intArray, int comparisons) {
int iFirst = 0;
int iSecond = 0;
int i = 0;
//moving the smaller element into intArray
while(iFirst < first.length && iSecond < second.length) {
comparisons++;
if(first[iFirst] < second[iSecond]) {
intArray[i] = first[iFirst];
iFirst++;
}
else {
intArray[i] = second[iSecond];
iSecond++;
}
i++;
}
//copying the remaining of first array
while(iFirst < first.length) {
intArray[i] = first[iFirst];
iFirst++; i++;
}
//copying the remaining of second array
while(iSecond < second.length)
{
intArray[i] = second[iSecond];
iSecond++; i++;
}
return comparisons;
}