【问题标题】:Counting the comparisons in quicksort计算快速排序中的比较
【发布时间】:2020-11-30 20:33:35
【问题描述】:

我需要帮助计算这些函数完成的比较次数。我已经声明了一个变量 compCount 来存储比较的数量,但请帮助找出放置 compCount++ 增量器的位置。

我了解您在执行 .compare 函数时会放置计数增量器,但存在像这样的复杂循环:

for (i = low, j = high - 1;;) {
            
            while (a[++i].compareTo(pivot) < 0) {
                
            }
            
            while (pivot.compareTo(a[--j]) < 0) {
                
            }
            
            if (i >= j) {
                break;
            }
            
            swapReferences(a, i, j);
        }

还有在insertionSort()函数中

代码如下:

public class QuickSort implements Sort {
long compCount;

/**
 * Quicksort algorithm.
 * 
 * @param a an array of Comparable items.
 */
@SuppressWarnings("rawtypes")
public void QuickSort(Comparable[] a) {
    compCount = 0;
    sort(a);
}

private static final int CUTOFF = 10;

/**
 * Method to swap to elements in an array.
 * 
 * @param a      an array of objects.
 * @param index1 the index of the first object.
 * @param index2 the index of the second object.
 */
public static void swapReferences(Object[] a, int index1, int index2) {
    Object tmp = a[index1];
    a[index1] = a[index2];
    a[index2] = tmp;
}

/**
 * Internal quicksort method that makes recursive calls. Uses median-of-three
 * partitioning and a cutoff of 10.
 * 
 * @param a    an array of Comparable items.
 * @param low  the left-most index of the subarray.
 * @param high the right-most index of the subarray.
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
private void quicksort(Comparable[] a, int low, int high) {
    if (low + CUTOFF > high)
        insertionSort(a, low, high);
    else {
        // Sort low, middle, high
        
        int middle = (low + high) / 2;
        if (a[middle].compareTo(a[low]) < 0) {
            
            swapReferences(a, low, middle);
        }
        if (a[high].compareTo(a[low]) < 0) {
            
            swapReferences(a, low, high);
        }
        if (a[high].compareTo(a[middle]) < 0) {
            
            swapReferences(a, middle, high);
        }
        // Place pivot at position high - 1
        swapReferences(a, middle, high - 1);
        Comparable pivot = a[high - 1];

        // Begin partitioning
        int i, j;
        for (i = low, j = high - 1;;) {
            
            while (a[++i].compareTo(pivot) < 0) {
                
            }
            
            while (pivot.compareTo(a[--j]) < 0) {
                
            }
            
            if (i >= j) {
                break;
            }
            
            swapReferences(a, i, j);
        }

        // Restore pivot
        swapReferences(a, i, high - 1);

        quicksort(a, low, i - 1); // Sort small elements
        quicksort(a, i + 1, high); // Sort large elements
    }
}

/**
 * Internal insertion sort routine for subarrays that is used by quicksort.
 * 
 * @param a   an array of Comparable items.
 * @param low the left-most index of the subarray.
 * @param n   the number of items to sort.
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
private void insertionSort(Comparable[] a, int low, int high) {
    for (int p = low + 1; p <= high; p++) {
        Comparable tmp = a[p];
        int j;
        
        for (j = p; j > low && tmp.compareTo(a[j - 1]) < 0; j--) {
            
            a[j] = a[j - 1];
        }
        
        a[j] = tmp;
    }
}

@SuppressWarnings("rawtypes")
@Override
public void sort(Comparable[] a) {
    // TODO Auto-generated method stub
    compCount = 0;
    quicksort(a, 0, a.length - 1);
}

@Override
public long getCompares() {
    // TODO Auto-generated method stub
    return compCount;
}

}

【问题讨论】:

  • 嗨,调用 compareTo 时可能算数吗?
  • 您需要将compCount++ 放置在每个while 循环内(以说明每次比较小于0)和在每个while 循环之后(以说明1 次比较不小于0 )。

标签: java arrays sorting


【解决方案1】:

好的,感谢我的朋友,我想通了。原来你应该计算 if 语句之外的比较而不是内部的,而且我还错过了一些条件:

代码如下:

public class QuickSort implements Sort {
long compCount;

/**
 * Quicksort algorithm.
 * 
 * @param a an array of Comparable items.
 */
@SuppressWarnings("rawtypes")
public void QuickSort(Comparable[] a) {
    compCount = 0;
    sort(a);
}

private static final int CUTOFF = 10;

/**
 * Method to swap to elements in an array.
 * 
 * @param a      an array of objects.
 * @param index1 the index of the first object.
 * @param index2 the index of the second object.
 */
public static void swapReferences(Object[] a, int index1, int index2) {
    Object tmp = a[index1];
    a[index1] = a[index2];
    a[index2] = tmp;
}

/**
 * Internal quicksort method that makes recursive calls. Uses median-of-three
 * partitioning and a cutoff of 10.
 * 
 * @param a    an array of Comparable items.
 * @param low  the left-most index of the subarray.
 * @param high the right-most index of the subarray.
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
private void quicksort(Comparable[] a, int low, int high) {
    if (low + CUTOFF > high) {
        insertionSort(a, low, high);
    }
    else {
        // Sort low, middle, high
        int middle = (low + high) / 2;
        
        if (a[middle].compareTo(a[low]) < 0) {
            swapReferences(a, low, middle); 
        }
        compCount++;
        if (a[high].compareTo(a[low]) < 0) {
            swapReferences(a, low, high);
        }
        compCount++;
        if (a[high].compareTo(a[middle]) < 0) {
            swapReferences(a, middle, high);    
        }
        compCount++;
        // Place pivot at position high - 1
        swapReferences(a, middle, high - 1);
        Comparable pivot = a[high - 1];

        // Begin partitioning
        int i, j;
        for (i = low, j = high - 1;;) {
            
            while (a[++i].compareTo(pivot) < 0) {
                compCount++;
            }
            compCount++;
            while (pivot.compareTo(a[--j]) < 0) {
                compCount++;
            }
            compCount++;
            if (i >= j) {
                break;
            }
            
            swapReferences(a, i, j);
        }

        // Restore pivot
        swapReferences(a, i, high - 1);

        quicksort(a, low, i - 1); // Sort small elements
        quicksort(a, i + 1, high); // Sort large elements
    }
}

/**
 * Internal insertion sort routine for subarrays that is used by quicksort.
 * 
 * @param a   an array of Comparable items.
 * @param low the left-most index of the subarray.
 * @param n   the number of items to sort.
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
private void insertionSort(Comparable[] a, int low, int high) {
    for (int p = low + 1; p <= high; p++) {
        Comparable tmp = a[p];
        int j;
        for (j = p; j > low && tmp.compareTo(a[j - 1]) < 0; j--) {
            compCount++;
            a[j] = a[j - 1];
        }
        
        if(j > low)
            compCount++;
        a[j] = tmp;
    }
}

@SuppressWarnings("rawtypes")
@Override
public void sort(Comparable[] a) {
    // TODO Auto-generated method stub
    compCount = 0;
    quicksort(a, 0, a.length - 1);
}

@Override
public long getCompares() {
    // TODO Auto-generated method stub
    return compCount;
}

}

【讨论】:

    猜你喜欢
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多