【发布时间】:2015-07-20 13:19:37
【问题描述】:
我正在学习斯坦福大学提供的 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,这是错误的。 有人可以指出我是否在这里遗漏了什么?附言我已经做了好几天了,如果有人帮助我,我将不胜感激!
【问题讨论】:
-
你为什么要
count += right - left - 1;? -
我需要计算每个递归调用。我假设计数增加了
M - 1,其中 M 是子数组的大小。 -
你确定数组排序正确吗?尝试使用不同的输入数据。您似乎跳过了分区中的第一个元素,这在常见的快速排序中是有意义的,针对随机输入进行了优化,它使用第一个元素作为枢轴。但是您正在使用中间输入位置的数据作为枢轴,因此跳过第一个是行不通的。
-
是的,我检查过多次。我将继续检查不同的数据集。如果你仔细看,在分区之前,我将中间元素与第一个交换。
int pivot = arr[mid]; arr[mid] = arr[left]; arr[left] = pivot; -
我错过了那个exch。所以我现在相信你它分类正确。我仍然看不到直接计数如何给出错误答案,我也看不到直接计数如何与您的原始答案相匹配(正如您所说的那样),在我看来,这似乎算得太多了,也没有直接计数会失败符合我的其他建议。您“正确”比较次数的来源是什么?
标签: c++ algorithm sorting quicksort