使用中间元素作为透视C++计算快速排序中的比较数
Counting number of comparisons in Quick Sort using middle element as Pivot C++
我正在上斯坦福大学提供的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,这是错误的。有人能指出我是否遗漏了什么吗?附言:我已经做了好几天了,所以如果有人帮我,我会非常感激的!
当你想计数时,直接的方法就是计算你正在计数的东西。据我所知,您需要计算执行以下行的次数:
if (arr[track] < pivot)
所以你所需要做的就是把++count;
放在这行前面。如果你想做更少的计算和/或了解更多,仔细想想它被执行了多少次:
编辑:当我在---下面写东西的时候,我真的没有想。这是错误的。因此,直接计数与计算计数的原始方法相匹配。我测试了你的代码,现在相信你正在计算正确的计数。试着用桌面检查一个小例子,并解释为什么你认为巨大的计数是错误的。
我无法访问您的数据文件,因此我无法确认或拒绝您的程序为该文件计算正确的计数。
for (int track = left + 1; track < right; track++)
该循环最多执行其正文(右-左-2(次。既然你在这一点上知道右>左,那么准确地说(而不是"最多"(右-左-2是安全的。
我认为您的计数计算正确。但全球统计是如此的不恰当,我认为这必须得到纠正。您可以通过从更改来完全消除该变量
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;
count += right - left - 1;
我觉得,在这里尝试使用"右-左"。由于"右-左+1"实际上是子数组的长度,这将给出您正在寻找的M-1。希望这能有所帮助!
用于选择中间元素的中间索引不正确。你没有考虑到这样一个事实,即你将左和右作为数组中的某些点发送,而不是作为0和n。例如,如果你有[5,4,2,1,6,7],并且你发送这个数组的右半部分,那么你的左将是3,右将是5(索引(。这个数组的中值是6,但这个数字的索引实际上是4。这里的行返回的是(5+3-1(/2=3,这是不正确的。注:我假设权利是你们最后的要素。
int mid = (right + left - 1)/2;
试着这样做吧,让你的数组接受左边为0,右边为数组的长度
int mid = ceil((right-left)/2) - 1 + left
你也可以使用旧的(right+left-1(/2的方式,但一定要做一次ceil并仔细检查,看看你是否真的选择了正确的中值。
- 如何修复我的快速排序实现?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在 MIPS 中快速排序
- 不正确的比较和交换计数器输出用于快速排序功能
- 使用 std::vector C++快速排序,EXC_BAD_ACCESS代码 2
- 使用快速排序对 C++ 中的可视化工具错误进行排序
- 快速排序 - 三个中位数枢轴选择 - 某些元素顺序不正确
- 并行快速排序分区中的隔离错误
- 实现 3 路分区以实现快速排序
- 为什么这个快速排序实现给出了一个奇怪的输出
- 我的快速排序在对预排序的项目进行排序时失败,如何改进?
- 快速排序不适用于大型数组
- 快速排序;分段错误,但找不到位置?
- 快速排序函数在快速排序算法中如何工作?
- 3路随机快速排序分区功能
- 在最坏的情况下试验快速排序.它运行良好,但在最坏的情况下发生未知错误.我想
- 当给出预先排序的输入时,为什么我的快速排序实现很慢
- 在快速排序中计算比较
- 计算快速排序中的比较次数
- 使用中间元素作为透视C++计算快速排序中的比较数