如何计算Quicksort算法中元素比较的数量?

时间:2011-03-01 03:36:14

标签: algorithm quicksort

给定一个元素数组时,如何计算算法执行的元素比较量?

这并不像在分区方法中添加计数器那么容易。

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也是如此),但如果我这样做的话,我觉得我仍然错过了某些事情。

3 个答案:

答案 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,然后总是执行第二个。