给定一个元素数组时,如何计算算法执行的元素比较量?
这并不像在分区方法中添加计数器那么容易。
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++;
j--;
}
}
你不能这样做,因为它计算刚刚进行的比较,而不是计算结果为false时的任何比较。
我已经尝试将if (array[i] < pivot)
更改为while (array[i] < pivot)
(对于j也是如此),但如果我这样做的话,我觉得我仍然错过了某些事情。
答案 0 :(得分:1)
理想情况下,你应该能够通过分析逻辑来做到这一点。但是如果你想让程序在运行期间为你做,那么简单的方法就是有一个执行比较操作的功能。让函数在每次调用时递增一个全局/静态变量,然后进行比较。在所有逻辑结束时,只需打印此全局/静态变量。
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.
答案 1 :(得分:1)
快速排序的parition方法将被调用,直到数组的大小不为1,在这种情况下我们的数组将被排序。在你的代码中,当你有founf交换枢轴的位置时(在你的其他部分)你不应该参加比较计数器。
您可以使用此修改后的分区方法
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;
}
在上面的算法中,你可以将countcompare视为全局,这将会对每次分区调用产生影响。这将计算所做的比较。
答案 2 :(得分:0)
您可以在每个if语句中嵌入比较计数增量...
if ((compareCount++ != -1) && (array[i] < pivot))
...
else if ((compareCount++ != -1) && (numbers[j] > pivot))
...
else if ((compareCount++ != -1) && (i <= j))
它总是会评估if的第一个子句,总是返回true,然后总是执行第二个。