【问题标题】:Should checking loop conditions be counted towards total number of comparisons?检查循环条件是否应计入比较总数?
【发布时间】:2015-08-30 11:08:54
【问题描述】:

我已经实现了三种不同的排序算法,现在我想确认我计算比较总数的方法是正确的。在我看来,比较的数量不应该与条件分支相关联,因为如果不满足条件,仍然会进行比较以比较值。我也使用同样的思考过程为退出循环条件的比较计数加一。

我的算法的实现如下。我是否在每种情况下都正确设置了计数器?

插入排序

int insertionSort(double* A, int arrayLength) {
    int count = 1; // Initialized 1 to count for exit conditions of for loop
    for (int j = 1; j < arrayLength; j++) {
        count++;
        double key = A[j];
        int i = j - 1;

        while (i > -1 && A[i] > key) {
            count++;
            A[i + 1] = A[i];
            i = i - 1;
        }

        count+=2 // Plus 2 for the while loop exit condition

        A[i + 1] = key;
    }

return count;
}

堆排序

void heapSort(double* A, int arrayLength, int* c) {
    int heapSize = 0;
    buildMaxHeap(A, arrayLength, &heapSize, c);

    for (int i = arrayLength - 1; i > 0; i--) {
        swap(A[0], A[i]);
        heapSize = heapSize - 1;
        maxHeapify(A, 0, &heapSize, c);
    }
}

void buildMaxHeap(double* A, int arrayLength, int* heapSize, int* c) {
    *heapSize = arrayLength - 1;
    *c = *c + 1; // Counts comparison of loop for exit condition
    for (int i = floor((arrayLength)/ 2); i > -1; i--) {
        *c = *c + 1;
        maxHeapify(A, i, heapSize, c);
    }
}
void maxHeapify(double* A, int i, int* heapSize, int* c) {
    int l = (2 * i) + 1;
    int r = (2 * i) + 2;
    int largest;

    if (l <= *heapSize && A[l] > A[i])
        largest = l;
    else largest = i;

    if (r <= *heapSize && A[r] > A[largest])
        largest = r;

    if (largest != i) {
        swap(A[i], A[largest]);
        maxHeapify(A, largest, heapSize, c);
    }

    *c = *c + 5;
}

快速排序

void quickSort(double* A, int p, int r, int* c) {

    if (p < r) {
        int q = partition(A, p, r, c);
        quickSort(A, p, q - 1, c);
        quickSort(A, q + 1, r, c);
        }
    *c = *c + 1;
}

int partition(double* A, int p, int r, int* c) {
    double x = A[r];
    int i = p - 1;

    for (int j = p; j < r; j++) {
        if (A[j] <= x) {
            i = i + 1;
            swap(A[i], A[j]);
        }
        *c = *c + 2;
    }

    *c = *c + 1 // Adding 1 for for loop exit condition

    swap(A[i + 1], A[r]);
    return i + 1;
}

【问题讨论】:

  • 您是要检查算法的实现还是询问如何检查每个算法中完成的比较次数?
  • @shunya 我知道算法是正确的。我的问题如前所述。我是否在每个算法中正确设置了计数器来计算所有比较?
  • 通常,排序算法的“比较次数”是指元素被比较的次数。

标签: c++ algorithm sorting c++11


【解决方案1】:

如果您查看插入排序

因为你已经把 count =1 放在了 for 循环的退出条件上。

出于同样的原因,当 while 循环取消时,内部的 count++ 将不会被执行,但进行了比较也是有意义的。 但你做了一个计数+=2。为什么2? 这是有道理的,因为您在 while 循环中进行 2 次比较时添加了 2

(i > -1 && A[i] > key)
  • i>-1
  • A[i] > 键

但是您需要在 while 循环内将计数器增加 2,因为每次 while 都是正确的,因此会进行 2 次比较。

int insertionSort(double* A, int arrayLength) {
    int count = 1; // Initialized 1 to count for exit conditions of for loop
    for (int j = 1; j < arrayLength; j++) {
        count++;
        double key = A[j];
        int i = j - 1;

        while (i > -1 && A[i] > key) {
            count++;
            A[i + 1] = A[i];
            i = i - 1;
        }

        count+2 // Plus 2 for the while loop exit condition

        A[i + 1] = key;
    }

return count;
}

您也可以检查其他算法。

仍然为了更好的方法,我建议您阅读任何有关算法分析的书籍中的一些起始章节。他们通常会解释如何估计算法的运行时间,这将有助于您了解如何更好地分析。

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 2011-03-24
    • 2015-06-25
    • 2016-05-12
    相关资源
    最近更新 更多