Merge sort algorithm not working - java

Here is my code for a mergesort in java:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(left, right, input);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}
My issue is that I'm getting an out of bounds exception.
I'm using the debugger and have found that after mergesort(left) and mergesort(right) have finished recursively running.
The arrays left and right, which go into the merge function, have the values [3] and [4] respectively, which is correct.
But when the debugger jumps into the merge function, left has value [3] and right, for some reason is length 2 and has the value [3,4].
This is the source of my out of bounds exception, though I'm not sure why when the merge function runs for its first time, it changes the value of "right".

One problem that is readily visible is that the you shouldn't make 2 arrays of size inputSize/2. Make two arrays of inputSize/2 and inputsize-inputSize/2. Otherwise the algorithm would fail for odd length array.
Also call the function with proper order of the arguments. merge( input, left, right);

I fixed your code and merged them to 1 method, left.length and right.length are limited by input.length so you only need to loop by input.length:
public static void mergeSort(int[] input)
{
if (input.length < 2)
{
return;
}
int[] left = new int[input.length / 2];
int[] right = new int[input.length - input.length / 2];
for (int i = 0; i < input.length; i++)
{
if (i < input.length / 2)
left[i] = input[i];
else
right[i - input.length / 2] = input[i];
}
mergeSort(left);
mergeSort(right);
for (int i = 0, l = 0, r = 0; i < input.length; i++)
{
if (l >= left.length)
{
input[i] = right[r];
r++;
}
else if (r >= right.length)
{
input[i] = left[l];
l++;
}
else
{
if (left[l] >= right[r])
{
input[i] = right[r];
r++;
}
else
{
input[i] = left[l];
l++;
}
}
}
}

you had two problems with your code:
1- as #coderredoc said: your left and right array sizes are wrong:
exemple: if you had an array of 7 elements, your left and right arrays would have a size of 7/2 = 3 so you would have a total of 6 elements in left and right arrays and not 7.
2- you are calling merge function in the mergeSort function with wrong parameters order:
it should be returnArr, left, right and not left,right, returnArr.
Explanation:
if you pass the left array as the first parameter, it would merge the right and the returnArr in the left array. But your left array has a size of 3 and the sum of the sizes of the others is 7 + 3 = 10 that's why you got an OutOfBoundsException.
you need to call merge(input,left,right);
here is the final version:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize-inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(input,left, right);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}

Related

Finding sorted subarrays in array

I am working on sorting algorithms and I am trying to improve mergeSort by locating already sorted subArrays.
public static void mergeSort(int[] array)
{
if(array == null)
{
return;
}
if(array.length > 1)
{
int mid = array.length / 2;
// left
int[] left = new int[mid];
for(int i = 0; i < mid; i++)
{
left[i] = array[i];
}
//right
int[] right = new int[array.length - mid];
for(int i = mid; i < array.length; i++)
{
right[i - mid] = array[i];
}
//recursively calls
mergeSort(left);
mergeSort(right);
int i = 0;
int j = 0;
int k = 0;
// left and right merged
while(i < left.length && j < right.length)
{
if(left[i] < right[j])
{
array[k] = left[i];
i++;
}
else
{
array[k] = right[j];
j++;
}
k++;
}
// left overs
while(i < left.length)
{
array[k] = left[i];
i++;
k++;
}
while(j < right.length)
{
array[k] = right[j];
j++;
k++;
}
}
}
What you are looking for is called natural merge sort. Before you start with sorting the dataset you will do one run to identify all the presorted data. The mergesort itself stays the same.
I found some example code for you at: happycoders
package eu.happycoders.sort.method.mergesort;
import eu.happycoders.sort.method.Counters;
import eu.happycoders.sort.method.SortAlgorithm;
/**
* Natural merge sort implementation for performance tests.
*
* #author Sven Woltmann
*/
public class NaturalMergeSort implements SortAlgorithm {
#Override
public void sort(int[] elements) {
int numElements = elements.length;
int[] tmp = new int[numElements];
int[] starts = new int[numElements + 1];
// Step 1: identify runs
int runCount = 0;
starts[0] = 0;
for (int i = 1; i <= numElements; i++) {
if (i == numElements || elements[i] < elements[i - 1]) {
starts[++runCount] = i;
}
}
// Step 2: merge runs, until only 1 run is left
int[] from = elements;
int[] to = tmp;
while (runCount > 1) {
int newRunCount = 0;
// Merge two runs each
for (int i = 0; i < runCount - 1; i += 2) {
merge(from, to, starts[i], starts[i + 1], starts[i + 2]);
starts[newRunCount++] = starts[i];
}
// Odd number of runs? Copy the last one
if (runCount % 2 == 1) {
int lastStart = starts[runCount - 1];
System.arraycopy(from, lastStart, to, lastStart,
numElements - lastStart);
starts[newRunCount++] = lastStart;
}
// Prepare for next round...
starts[newRunCount] = numElements;
runCount = newRunCount;
// Swap "from" and "to" arrays
int[] help = from;
from = to;
to = help;
}
// If final run is not in "elements", copy it there
if (from != elements) {
System.arraycopy(from, 0, elements, 0, numElements);
}
}
private void merge(int[] source, int[] target, int startLeft,
int startRight, int endRight) {
int leftPos = startLeft;
int rightPos = startRight;
int targetPos = startLeft;
// As long as both arrays contain elements...
while (leftPos < startRight && rightPos < endRight) {
// Which one is smaller?
int leftValue = source[leftPos];
int rightValue = source[rightPos];
if (leftValue <= rightValue) {
target[targetPos++] = leftValue;
leftPos++;
} else {
target[targetPos++] = rightValue;
rightPos++;
}
}
// Copy the rest
while (leftPos < startRight) {
target[targetPos++] = source[leftPos++];
}
while (rightPos < endRight) {
target[targetPos++] = source[rightPos++];
}
}
#Override
public void sort(int[] elements, Counters counters) {
// Not implemented
}
}

Java Natural Merge Sort implementation

I can be considered new in Java . I ' ve been struggling with one question which was given to us by our professor in our school. I am supposed to make a natural merge sort algorithm which has to find two sorted sub-arrays everytime and merge them.(which is a version of bottom up merge sort). But i am stuck here is my code
public class NaturalMergeMine {
private static Comparable[] aux;
public static void sort(Comparable[] a) {
aux = new Comparable[a.length];
sort(a, 0, a.length - 1);
}
public static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i += 1) {
if (a[i - 1].compareTo(a[i]) < 0) {
return false;
}
}
return true;
}
private static void sort(Comparable[] a, int lo, int hi) {
int i = lo;
int j = 0;
int mid = 0;
int az = 0;
while (true) {
i = 0;
System.out.println("outter");
while (i < a.length) {
System.out.println("inner 1");
if (i == a.length - 1) {
break;
} else if (a[i].compareTo(a[i + 1]) < 0) {
break;
}
i++;
}
j = i + 1;
while (j < a.length) {
System.out.println("inner 2");
if (j == a.length - 1) {
break;
} else if (a[j].compareTo(a[j + 1]) < 0) {
break;
}
j++;
}
mid = lo + (j - lo) / 2;
Merge(a, lo, mid, j);
lo = 0;
if (isSorted(a)) {
break;
}
}
}
public static void Merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo;
int j = mid + 1;
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
for (int k = lo; k <= hi; k++) {
if (i > mid) {
a[k] = aux[j++];
} else if (j > hi) {
a[k] = aux[i++];
} else if (aux[i].compareTo(aux[j]) < 0) {
a[k] = aux[j++];
} else {
a[k] = aux[i++];
}
}
}
public static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
public static void main(String[] args) {
Integer[] arr = {6, 4, 5, 7, 8, 3, 2, 1};
sort(arr);
show(arr);
}
}
what happens is that it is not merging correctly and it goes in an infinite loop in the outter loop ,which is because it is not sorted properly. Is there anyone who can advice me a better way or can tell me the mistake i make here. Thanks in advance.
The issue is in the mid calculation, im not quite sure why you do that,but if the mid is less than i in you merge method you wont reach the fault case so you will stuck in discovering it without solving, for each run you need to pick up two arrays to sort, so instead of mid you can insert i to the merge method so you start the merging from the fault in.
public class NaturalMergeMine {
private static Comparable[] aux;
public static void sort(Comparable[] a) {
aux = new Comparable[a.length];
sort(a, 0, a.length - 1);
}
public static boolean isSorted(Comparable[] a) {
for (int i = 1; i < a.length; i += 1) {
if (a[i - 1].compareTo(a[i]) > 0) {//changed operator to greater than
return false;
}
}
return true;
}
private static void sort(Comparable[] a, int lo, int hi) {
int i = lo;
int j = 0;
int mid = 0;
int az = 0;
while (true) {
i = 0;
System.out.println("outter");
while (i < a.length) {
System.out.println("inner 1");
if (i == a.length - 1) {
break;
} else if (a[i].compareTo(a[i + 1]) > 0) {//changed operator to greater than
break;
}
i++;
}
j = i + 1;
while (j < a.length) {
System.out.println("inner 2");
if (j == a.length - 1) {
break;
} else if (a[j].compareTo(a[j + 1]) > 0) {//changed operator to greater than
break;
}
j++;
}
// mid = lo + (j - lo) / 2;
Merge(a, lo, i, j);
lo = 0;
if (isSorted(a)) {
break;
}
}
}
public static void Merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo;
int j = mid + 1;
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
for (int k = lo; k <= hi; k++) {
if (i > mid) {
a[k] = aux[j++];
} else if (j > hi) {
a[k] = aux[i++];
} else if (aux[i].compareTo(aux[j]) > 0) {//changed the operator to greater than
a[k] = aux[j++];
} else {
a[k] = aux[i++];
}
}
}
public static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
public static void main(String[] args) {
Integer[] arr = {6, 4, 5, 7, 8, 3, 2, 1};
sort(arr);
show(arr);
}
}
Amer Qarabsa's answer fixes the problems with the original code. Below are some alternate examples that are a bit more optimized, scanning the array for pairs of ascending sequences, rather than starting over at the beginning each time. If the array was reversed, then the first pass creates runs of 2, the next pass runs of 4, ... . With the original version, the run size would only increase by one on each loop. The example code below uses open intervals (last index is end of array instead of last element of array).
public class jsortns {
private static Comparable[] aux;
public static void sort(Comparable[] a) {
aux = new Comparable[a.length];
int i;
int j;
int k;
while (true) { // merge pass
i = 0;
while(true) { // find, merge pair of runs
j = i; // find left run
while (++j < a.length) {
if (a[j-1].compareTo(a[j]) > 0)
break;
}
if(j == a.length){ // if only one run left
if(i == 0) // if done return
return;
else // else end of merge pass
break;
}
k = j; // find right run
while (++k < a.length) {
if (a[k-1].compareTo(a[k]) > 0){
break;
}
}
Merge(a, i, j, k); // merge runs
i = k;
if(i == a.length) // if end of merge pass, break
break;
}
}
}
// merge left and right runs
// ll = start of left run
// rr = start of right run == end of left run
// ee = end of right run
public static void Merge(Comparable[] a, int ll, int rr, int ee) {
int i = ll;
int j = rr;
int k;
for (k = ll; k < ee; k++)
aux[k] = a[k];
k = ll;
while(true){
// if left element <= right element
if (aux[i].compareTo(aux[j]) <= 0) {
a[k++] = aux[i++]; // copy left element
if(i == rr){ // if end of left run
while(j < ee) // copy rest of right run
a[k++] = aux[j++];
return; // and return
}
} else {
a[k++] = aux[j++]; // copy right element
if(j == ee){ // if end of right run
while(i < rr){ // copy rest of left run
a[k++] = aux[i++];
}
return; // and return
}
}
}
}
No copy back version, instead merges back and forth between two arrays, and only copies at the end if the sorted data ends up in the wrong array.
public class jsortns {
private static Comparable[] b; // temp array
private static Comparable[] o; // original array reference
private static Comparable[] t; // used to swap a, b
public static void sort(Comparable[] a) {
o = a; // save ref to a
b = new Comparable[a.length]; // allocate temp array
int i;
int j;
int k;
while (true) { // merge pass
i = 0;
while(true) { // find, merge pair of runs
j = i; // find left run
while (++j < a.length) {
if (a[j-1].compareTo(a[j]) > 0)
break;
}
if(j == a.length){ // if only one run left
if(i != 0){ // if not done
while(i < j){ // copy run to b
b[i] = a[i];
i++;
}
break; // break to end merge pass
} else { // else sort done
if(a != o){ // if a not original a, copy
for(i = 0; i < a.length; i++)
b[i] = a[i];
}
return;
}
}
k = j; // find right run
while (++k < a.length) {
if (a[k-1].compareTo(a[k]) > 0){
break;
}
}
Merge(a, b, i, j, k); // merge left, right into b
i = k;
if(i == a.length) // break if end pass
break;
}
t = a; // swap a and b (references)
a = b;
b = t;
}
}
// merge left and right runs from a[] to b[]
// ll = start of left run
// rr = start of right run == end of left run
// ee = end of right run
public static void Merge(Comparable[] a, Comparable[] b, int ll, int rr, int ee) {
int i = ll;
int j = rr;
int k = ll;
while(true){
// if left element <= right element
if (a[i].compareTo(a[j]) <= 0) {
b[k++] = a[i++]; // copy left element
if(i == rr){ // if end of left run
while(j < ee) // copy rest of right run
b[k++] = a[j++];
return; // and return
}
} else {
b[k++] = a[j++]; // copy right element
if(j == ee){ // if end of right run
while(i < rr){ // copy rest of left run
b[k++] = a[i++];
}
return; // and return
}
}
}
}

exception in merge for non-iterative mergesort algorithm

I'm trying to create a non-recursive version of MergeSort but for some reason merge is keeping the code from running in its entirety.
Mergesort Code:
public void mergeSort(int[] input)
{
int n = input.length;
int size;
int l;
for (size = 1; size <= n-1; size = 2*size)
{
for (l = 0; l < n-1; l += 2*size)
{
int m = l + size -1;
int r = minimum(l + 2*size - 1, n-1);
merge(input, l, m, r);
}
}
}
Merge code:
public static void merge(int[] numbers, int low, int middle, int high)
{
// Copy both parts into the helper array
int helper[];
helper = new int[numbers.length];
for (int i = low; i <= high; i++) {
helper[i] = numbers[i];
}
int i = low;
int j = middle + 1;
int k = low;
// Copy the smallest values from either the left or the right side back
// to the original array
while (i <= middle && j <= high) {
if (helper[i] <= helper[j]) {
numbers[k] = helper[i];
i++;
} else {
numbers[k] = helper[j];
j++;
}
k++;
}
// Copy the rest of the left side of the array into the target array
while (i <= middle) {
numbers[k] = helper[i];
k++;
i++;
}
}
This is how I fill up the input array (which is of size 100):
public static int fillArray()
{
Random r = new Random();
int rand = r.nextInt();
return rand;
}
//followed by these lines of code in the main method:
int[] arr;
arr = new int[100];
for(int i =0; i<arr.length; i++)
{
arr[i] = fillArray();
}
The exception is with numbers[k] = helper[i] in merge().
I know that the contents of the input array are fine because I print out the contents of the array before I perform MergeSort on it. Does anyone know what the problem is?
Fix the m in mergeSort() like this:
int m = Math.min(l + size - 1, n - 1);
You didn't mention what exception you get but I assume its array out of bounds. What prevents your middle variable from exceeding the size of the array?
while (i <= middle) {
numbers[k] = helper[i];
k++;
i++;
}
Put in debugging prints etc.

Merge Sort Example

I am new to Java and I have tried writing a Merge Sort Program .
MergeSort.java program is below :-
public class MergeSort {
public static int b[] = {6,2,3,1,9};
public void MergeSort(int a[],int left[], int right[]) {
int i = 0,j = 0,k = 0;
int l = left.length;
int r = right.length;
int v = a.length;
while ( i < l && j < r) {
if( left[i] < right[j]) {
a[k] = left[i] ;
i++;
} else {
a[k] = right [j];
j++;
}
k++;
}
while ( i < l ) {
a[k] = left[i];
k++;
i++;
}
while ( j < r ) {
a[k] = right[j];
k++;
j++;
}
}
public void Merge(int a[], int length) {
int n = length;
if(n < 2) return;
int mid = n/2;
int left[] = new int[mid];
int right[] = new int[n-mid];
for (int i = 0 ; i <mid ; i++) {
left[i] = a[i];
}
for (int i = mid ; i <n ; i++) {
right[i-mid] = a[i];
}
Merge(right,n-mid);
Merge(left,mid);
MergeSort(b, left, right);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MergeSort ms = new MergeSort();
ms.Merge(b,b.length);
for(int i=0 ; i < b.length ; i++)
System.out.println(b[i]);
}
}
When I run this program , the output I get is
3
1
6
2
9
But , the expected output is 1 2 3 6 9
Can anyone please help me point out the mistake I am doing and try to help me fix it please .I have tried debugging it on Eclipse but could not spot the bug .
Thanks
Are you sure you meant this in function Merge:
MergeSort(b, left, right);
It seems it should be:
MergeSort(a, left, right);

Where are comparisons in java sorting methods?

Question: Where are comparisons being made in each separate sorting method?
Also if you know please tell me which method count numbers are wrong and where to place my counters instead.trying to understand where and how many times sorting methods make comparisons.
Method A B
Selection 4950 4950
Bubble 99 9900
Insertion 99 5049
Merge 712 1028
Shell 413 649
Quick 543 1041
Okay so to explain some parts, basically Array A is an array from 1-100 in ascending order. So this should be the minimum number of comparisons.
Array B is 100-1 in descending order. So I believe it should be the maximum number of comparisons. Array C is just randomly generated numbers, so it changes every time.
I feel like my selection and bubble sorts were counted correctly. Feel free to let me know where comparisons are being made that I haven't counted, or if I'm counting wrong comparisons.
Side note: Made some global variable to count the methods that were recursive in multiple sections.
class Sorting
{
static int[] X = new int[100];
static int mergecount = 0;
static int quickcount = 0;
public static void selectionSort(int list[])
{
int count = 0;
int position = 0, n = list.length;
for(int j = 0; j < n-1; j++)
{
position = j;
for(int k = j+1; k < n; k++)
{
count++;
if(list[k] < list[position])
position = k;
}
Swap(list, j, position);
}
System.out.println("counter" + count);
}
public static void Swap(int list[], int j, int k)
{
int temp = list[j];
list[j] = list[k];
list[k] = temp;
}
public static void bubbleSort(int list[])
{
int count = 0;
boolean changed = false;
do
{
changed = false;
for(int j = 0; j < list.length - 1; j++)
{
count++;
if(list[j] > list[j + 1])
{
Swap(list, j, j+1);
changed = true;
}
}
} while(changed);
System.out.println("counter" + count);
}
public static void insertionSort(int list[])
{
int count = 0;
for(int p = 1; p < list.length; p++)
{
int temp = list[p];
int j = p;
count++;
for( ; j > 0 && temp < list[j - 1]; j = j-1)
{
list[j] = list[j - 1];
count++;
}
list[j] = temp;
}
System.out.println("counter" + count);
}
public static void mergeSort(int list[])
{
mergeSort(list, 0, list.length - 1);
System.out.println("counter" + mergecount);
}
public static void mergeSort(int list[], int first, int last)
{
if(first < last)
{
int mid = (first + last) / 2;
mergeSort(list, first, mid);
mergeSort(list, mid + 1, last);
Merge(list, first, mid, last);
}
}
public static void Merge(int list[], int first, int mid, int last)
{
int count = 0;
int first1 = first, last1 = mid;
int first2 = mid + 1, last2 = last;
int temp[] = new int[list.length];
int index = first1;
while(first1 <= last1 && first2 <= last2)
{
if(list[first1] < list[first2])
{
temp[index] = list[first1++];
mergecount++;
}
else
temp[index] = list[first2++];
index++;
mergecount++;
}
while(first1 <= last1)
temp[index++] = list[first1++];
while(first2 <= last2)
temp[index++] = list[first2++];
for(index = first; index <= last; index++)
list[index] = temp[index];
}
public static void shellSort(int list[])
{
int count = 0;
int n = list.length;
for(int gap = n / 2; gap > 0; gap = gap == 2 ? 1: (int) (gap/2.2))
for(int i = gap; i < n; i++)
{
int temp = list[i];
int j = i;
count++;
for( ; j >= gap && (temp < (list[j - gap])); j -= gap)
{
list[j] = list[j - gap];
count++;
}
list[j] = temp;
}
System.out.println("counter" + count);
}
public static void quickSort(int start, int finish, int list[])
{
int count = 0;
int left = start, right = finish, pivot, temp;
pivot = list[(start + finish) / 2];
do
{
while(list[left] < pivot)
{
left++;
quickcount++;
}
while(pivot < list[right])
{
right--;
quickcount++;
}
if(left <= right)
{
temp = list[left];
list[left++] = list[right];
list[right--] = temp;
quickcount++;
}
} while(left < right);
if(start < right)
quickSort(start, right, list);
if(left < finish)
quickSort(left, finish, list);
}
public static void copy(int list[])
{
for(int i = 0; i < list.length; i++)
X[i] = list[i];
}
public static void restore(int list[])
{
for(int i = 0; i < list.length; i++)
list[i] = X[i];
}
public static void displayArray(int list[])
{
for(int k = 0; k < list.length; k++)
System.out.print(list[k] + " ");
System.out.println();
}
public static void main(String args[])
{
int[] A = new int[100];
for(int i = 0; i < A.length; i++)
A[i] = i + 1;
int[] B = new int[100];
int q = 100;
for(int i = 0; i < B.length; i++)
B[i] = q--;
int[] C = new int[100];
for(int i = 0; i < C.length; i++)
C[i] = (int)(Math.random() * 100 + 1);
displayArray(A);
copy(A);
selectionSort(A);
displayArray(A);
restore(A);
}
Note that QuickSort performance is greatly influenced by your choice of the pivot. With both of your test arrays sorted (ascending / descending) and because you are picking pivot as array[length/2] you are actually always picking the best pivot. So your test case B won't generate maximum number of comparisons for quicksort. If you were picking array[0] as pivot you'd get maximum number of comparisons for test case A and B.
The easiest way to count comparisons is to use a compare function and do it in there.
static int compareCount = 0;
int compareInt(int a, int b) {
compareCount++;
return a - b; // if 0 they are equal, if negative a is smaller, if positive b is smaller
}
Now just use compareInt in all your algorithms and you'll get an accurate count. You'll have to reset compareCount between each run though.

Categories