我已经了解了快速排序算法中的分割部分是如何完成的,但是我很难理解快速排序递归函数。有人可以一步一步向我解释一下它是如何工作的吗?我在这里粘贴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 (low < high)
将始终为真。第一次,
低(0)和高(9)值来自int main。quickSort(myArray, low, pi - 1);
函数调用开始并循环直到某些东西停止它,然后对第二个调用quickSort(myArray, pi + 1, high);
相同?还是在i + 1之前分区然后在i + 1之后分区并重新启动功能? 我知道这是一个基本问题,但是我真的很难理解这个算法。
答案 0 :(得分:3)
if (low < high) will always be true.
不正确。第一次调用时是正确的,但QuickSort会以low
和high
之间逐渐变小的间隔递归调用自身。这就是if
为何算法最终终止的原因-您在下面询问该问题。
Pi will be equal to the returned value of the partition funcion (i+1)
对。 pi
是数据透视表索引的缩写,即分区后所选数据透视表结束的位置。
And what if at this point the values are still not sorted?
分区后,您知道左分区中的任何值都不大于枢轴值,右分区中的任何值都不小于枢轴值。这就是您所知道的,并且所有算法都需要知道才能最终成功。每个分区都递归分区,直到其中只有一个元素为止。
when will this loop situation stop?
看到我的第一点。
答案 1 :(得分:2)
partition函数将枢轴元素放置在适当位置,并将索引返回到枢轴元素。接下来的两次调用不包含该元素,在最坏的情况下,一个调用将针对零个元素,另一个将对n-1个元素进行调用,并在最坏的情况下继续进行,对于每个递归级别,时间复杂度为O(n ^ 2)。最好的情况是,如果枢轴最终在中间,在每个递归级别上平均分配,或者对于时间复杂度O(n log(n))接近平均分配。