我已经理解了quicksort算法中的分区部分是如何完成的,但是我在理解quicksort递归函数时遇到了麻烦。谁能一步一步地给我解释一下它是怎么工作的吗?这里粘贴的是C++代码。
using namespace std;
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int myArray[], int low, int high) {
int i = (low - 1);
int pivot = myArray[high];
for (int j = low; j <= high - 1; j++) {
if (myArray[j] < pivot) {
i++;
swap(&myArray[i], &myArray[j]);
}
}
swap(&myArray[i + 1], &myArray[high]);
return (i + 1);
}
void quickSort(int myArray[], int low, int high) {
if (low < high) {
int pi = partition(myArray, low, high);
quickSort(myArray, low, pi - 1);
quickSort(myArray, pi + 1, high);
}
}
void cinArray(int myArray[], int n) {
for (int p = 0; p < n; p++) {
cin >> myArray[p];
}
}
void print(int myArray[], int n) {
for (int z = 0; z < n; z++) {
cout << myArray[z] << "\t";
}
}
int main() {
int myArray[10];
int size = sizeof(myArray) / sizeof(myArray[0]);
cout << "Write 10 numbers: ";
cinArray(myArray, size);
quickSort(myArray, 0, size - 1);
print(myArray, size);
return 0;
}
我的逻辑到目前为止(一步一步)是这样的:
if(低
将始终为true。第一次,低(0)和高(9)值取自int main。
- pi将等于分区函数的返回值(I+1),我认为为了返回该值,函数必须首先运行。
- 我们调用quicksort函数,两次为该函数提供新参数。一次用于原始分区之前的值,一次用于原始分区i+1之后的值。我想重点讨论第一个问题,即值在I+1之前的问题。
- 函数再次启动,if语句为true(始终为),pi调用函数分区并返回i+1,pi等于i+1。如果此时值仍未排序呢?我假设quicksort函数再次重新启动(感觉像是一个循环)。但既然IF语句将始终为真,那么这种循环情况何时才会停止呢?
- 同样,假设我在第4点的逻辑是正确的,那么代码第一次是如何运行的?它是否从第一个
quicksort(myArray,low,pi-1);
函数调用开始,循环直到某个东西停止它,然后对第二个调用quicksort(myArray,pi+1,high);
执行相同的操作?还是在i+1之前进行分区,然后在i+1之后重新启动函数?
我知道这是一个基本的问题,但我真的很难把我的头围绕在这个算法上。
if(低<高)始终为true。
不正确。这在第一次调用时是正确的,但是QuickSort调用自己是递归的,在low
和high
之间的间隔逐渐变小。这个if
是算法最终终止的原因--您将在下面询问这个问题。
pi将等于分区函数的返回值(i+1)
对啊。pi
是数据透视索引的缩写,即所选数据透视在分区后结束的位置。
如果此时值仍未排序,该怎么办?
分区后,您知道左侧分区中没有值大于透视值,右侧分区中没有值小于透视值。这就是你所知道的全部,算法为了最终成功需要知道的全部。每个分区都被递归分区,直到其中只有一个元素。
此循环情况何时停止?
看我的第一点。
/*尾部调用消除后的快速排序*/ 交换两个元素的效用函数 /*此函数将最后一个元素作为pivot,将pivot元素放置在排序数组中的正确位置,并将所有较小(小于pivot)的元素放置在pivot的左侧,将所有较大的元素放置在pivot的右侧。它使用的是Lomuto分区算法。*/ /*实现QuickSort的主要函数arr[]-->要排序的数组,低-->起始索引,高-->结束索引*/ 函数来打印数组
我想修改QuickSort(在Java中),这样每次调用Partition时,都会以比例数组的中值作为支点。 我在Java中有一个中值选择算法,它返回第k个最小的元素,在本例中是中值。我有大量的java快速排序算法,它们都可以独立工作,对数组进行排序。不幸的是,我不能结合这两者来实现上述目标...每次我尝试它,我通常得到堆栈溢出错误。 任何人都可以向我展示代码,看看它是如何完成的吗? 谢谢 编辑:
问题内容: 为了刷新一些Java,我尝试实现一种可以对整数数组进行排序的quicksort(inplace)算法。以下是到目前为止的代码。您可以通过拨打电话。 如果两个“指针”均指向与支点值相同的数组条目,则该代码显然会失败(陷入无限循环)。枢轴元素始终是当前分区的最右边(索引最大的分区)。 但是我无法弄清楚如何避免这种情况,有人看到解决方案了吗? 问题答案: 这应该可以工作( 稍后将检查正确性
问题内容: 我使用数组中的第一个元素作为枢轴实现了一个有效的quickSort算法,如下所示: 效果很好,但是如果我将更改为可以得到以下结果: 我如何使算法与数据透视表一起用作任何索引 问题答案: 您可以在开始排序之前简单地将所选的数据透视图与数组中的第一个元素交换,这样它将完全像以前一样工作。
我极度困惑。其中一个测验问题是"True or False, Quick ort在算法的征服阶段实现排序",我选择了true,因为我记得读过: 快速排序的三个步骤如下: 分割:重新排列元素,并将阵列分割为两个子阵列和中间的一个元素,以便左子阵列中的每个元素小于或等于中间元素,右子阵列中的每个元素大于中间元素。 征服:递归地对两个子数组排序。 组合:无。 然而,测验的答案说答案是错误的,没有任何解释
本文向大家介绍Javascript实现快速排序(Quicksort)的算法详解,包括了Javascript实现快速排序(Quicksort)的算法详解的使用技巧和注意事项,需要的朋友参考一下 目前,最常见的排序算法大概有七八种,其中"快速排序"(Quicksort)使用得最广泛,速度也较快。它是图灵奖得主C. A. R. Hoare(1934--)于1960时提出来的。 "快速排序"的思想很简单,