使用中间元素作为Pivot C ++计算快速排序中的比较次数

时间:2015-07-20 13:19:37

标签: c++ algorithm sorting quicksort

我参加了Coursera的课程:"算法的设计和分析"由斯坦福大学提供。以随机顺序提供具有10000个不同整数的文本文件。任务是在每次递归调用中使用中间元素作为枢轴执行快速排序后计算比较次数。

以下是文本文件的链接: https://drive.google.com/drive/u/0/folders/0B_WysIAkKMzzN3o4SEhoS0RjMUU

这就是我所做的:

#include <iostream>
#include <fstream>

using namespace std;

int partition(int arr[],int left,int pivot,int right);
int quickSort(int arr[], int left, int right);

int count = 0;

int partition(int arr[],int left,int pivot,int right) {
    int split = left + 1, tmp;

    for (int track = left + 1; track < right; track++) {
        if (arr[track] < pivot) {
            tmp = arr[track];
            arr[track] = arr[split];
            arr[split] = tmp;
            split++;
        }
    }

    tmp = arr[split - 1];
    arr[split - 1] = arr[left];
    arr[left] = tmp;
    return split - 1;
}


int quickSort(int arr[], int left, int right) {

    if (right <= left)
        return 0;

    int mid = (right + left - 1)/2;
    int pivot = arr[mid];
    arr[mid] = arr[left];
    arr[left] = pivot;
    int split = partition(arr,left,pivot,right);
    count += right - left - 1;

    quickSort(arr,left,split);
    quickSort(arr,split + 1,right);
    return count;
}

int main() {

    int ans;
    int arr[10001], i = 0;
    ifstream fin("QuickSort.txt");
    while (fin >> arr[i]) {
        i++;
    }
    fin.close();


    ans = quickSort(arr, 0, i);

    //To check if array is sorted
    for(int x = 0;x < i;x++) {
        cout<<arr[x]<<endl;
    }
    cout<<endl;

    cout << ans;
    return 0;
}

尽管数组排序正常,但计数为150657,这是错误的。 有人可以指出我在这里遗失了什么吗?附:我已经好几天了,所以如果有人帮助过我,我真的很感激!

3 个答案:

答案 0 :(得分:1)

当你想要计算某些东西时,直接的方法就是计算你的数量。据我所知,您想要计算执行以下行的次数:

if (arr[track] < pivot)

所以你需要做的就是把++count;放在那一行之前。如果你想减少计算和/或了解更多,请考虑执行它的次数:

编辑:当我写下---以下的东西时,我真的没想到。这是错的。因此,直接计数与您计算计数的原始方法相匹配。我测试了你的代码,现在相信你正在计算正确的数量。试试桌面检查一个小例子,并解释为什么你认为巨大的计数是错误的。

我无法访问您的数据文件,因此我无法确认或拒绝您的程序计算该文件的正确计数。

for (int track = left + 1; track < right; track++)

该循环最多会执行其身体(右 - 左2)次。既然你知道那时正确的&gt;就可以安全地说出(而不是“最多”)右 - 左2。

答案 1 :(得分:0)

我认为您的计数是正确计算的。但全球统计是不合适的,我认为必须予以纠正。您可以通过更改以下内容来完全消除该变量:

count += right - left - 1;

quickSort(arr,left,split);
quickSort(arr,split + 1,right);
return count;

return
   right - left - 1
+  quickSort(arr,left,split)
+  quickSort(arr,split + 1,right);

或计算本地计数,更改为:

int count = right - left - 1;

count += quickSort(arr,left,split);
count += quickSort(arr,split + 1,right);
return count;

答案 2 :(得分:0)

  count += right - left - 1;

我觉得,在这里尝试使用&#34;右 - 左&#34;。自&#34;右 - 左+ 1&#34;实际上是子阵列的长度,这将给你正在寻找的M-1。希望这可以帮助!