How can I count the number of element comparisons in the Quicksort algorithm?
When given an array of elements, how can I count the amount of element comparisons the algorithm performs?
It's not as easy as just adding a counter to the partition method.
private void partition(int low, int high) {
int i = low, j = high;
// Get the pivot element from the middle of the list
int pivot = numbers[low + (high-low)/2];
// Divide into two lists
while (i <= j) {
if (array[i] < pivot) {
i++;
compareCount++; //it's not as easy as just adding this here
}
else if (numbers[j] > pivot) {
j--;
compareCount++;
}
else (i <= j) {
exchange(i, j);
i++;
开发者_StackOverflow j--;
}
}
You can't do this because it counts the comparison just made, and not any of the comparisons made when it evaluates to false.
I've tried changing the if (array[i] < pivot)
to while (array[i] < pivot)
(for j, too), but I feel like I'm still missing out on something if I do it that way.
Ideally you should be able to do it by analyzing the logic. But if you want to have the program do it for you during its run-time then, easy way to do this is to have a function for performing comparison operation. Let the function increment a global/static variable everytime it is called and then do the comparison. At the end of all your logic just print this global/Static variable.
public class Myclass{
public static int compareCount = 0;
}
/*
* PASS parameter comparisonMethod as following
* 0 for ==, 1 for >, 2 for >=, 3 for < and 4 for <==
* Method returns true or false by doing appropriate comparison based on comparisonMethod
*/
public bool compare(int i, int j, int comparisonMethod)
{
Myclass.compareCount++;
if(comparisionMethod ==0) return i==j?true:false;
if(comparisionMethod ==1) return i>j?true:false;
if(comparisionMethod ==2) return i>=j?true:false;
if(comparisionMethod ==3) return i<j?true:false;
if(comparisionMethod ==4) return i<=j?true:false;
}
private void partition(int low, int high) {
int i = low, j = high;
// Get the pivot element from the middle of the list
int pivot = numbers[low + (high-low)/2];
// Divide into two lists
while (compare(i, j, 4)) {
if (compare(array[i], pivot, 3)) {
i++;
}
else if (compare(numbers[j], pivot, 2)) {
j--;
}
else (compare(i, j, 4)) {
exchange(i, j);
i++;
j--;
}
}
// At the end of the logic, Myclass.compareCount wil give number of comparisons made.
The parition method of quick sort would be called till the size of array is not 1 in which case our array would be sorted.In your code when you have founf the position at which pivot would be swapped (in your else if portion)you are not supposed to incrment the comparecounter.
You can use this modified partition method
partition(A,p,r)
{
pivot=A[r]; // Taking last element as pivot
i=p;
j=r;
while (true)
{
while(A[i] < pivot && i <= r )
{
++comparecounter;
++i;
}
while(A[j] >= pivot && j >= 0)
{
--j;
++comparecount;
}
if(i < j)
{
Exchange A[i] and A[j]
}
else
{
return j;
}
In above algorithm you could make countcompare as global which would would incrment fro each call to partition.This would would count the no of comparisions made.
You can embed the compare count increment inside each if statement...
if ((compareCount++ != -1) && (array[i] < pivot))
...
else if ((compareCount++ != -1) && (numbers[j] > pivot))
...
else if ((compareCount++ != -1) && (i <= j))
It'll always evaluate the first clause of the if, always return true, and always then execute the second.
精彩评论