快速排序函数在快速排序算法中如何工作?

How does the quicksort function work in a quicksort algorithm?

本文关键字:快速排序 工作 函数 算法 何工作      更新时间:2023-10-16

我已经了解了快速排序算法中的分区部分是如何完成的,但我在理解快速排序递归函数时遇到了麻烦。有人可以一步一步地向我解释它是如何工作的吗?我在这里粘贴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;
}

到目前为止,我的逻辑(一步一步(如下:

  1. if (low < high)永远是真的。第一次, 低 (0( 和高 (9( 值取自 int main。
  2. Pi 将等于分区函数的返回值 (i+1(,我想为了返回该值,函数 必须先跑。
  3. 我们调用快速排序函数,为函数提供两次新参数。一次 原始分区中 I+1 之后的值之前和一次的值。我想关注第一个上发生的事情,即在 i+1 之前具有值的那个。
  4. 函数再次启动,if 语句为真(始终为真(,pi 调用函数分区并返回 i+1,pi 等于 i+1。如果此时值仍未排序怎么办?我想快速排序功能再次重新启动(感觉就像一个循环(。但是,由于IF语句将始终为真,那么这种循环情况何时会停止?
  5. 另外,假设我在第 4 点的逻辑是正确的,代码第一次是如何运行的?它是否从第一个quickSort(myArray, low, pi - 1);函数调用开始并循环,直到某些东西停止它,然后对第二个调用quickSort(myArray, pi + 1, high);执行相同的操作?还是在 i+1 之前分区,然后在 i+1 之后分区并重新启动函数?

我知道这是一个基本问题,但我真的很难理解这个算法。

if (low < high) will always be true.

不正确。在第一次调用时为真,但 QuickSort 调用自己递归,lowhigh之间的间隔逐渐变小。这就是算法最终终止的原因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?

请看我的第一点。

分区函数将透视元素放置到位,并将索引返回到透视元素。接下来的两次调用排除了元素,在最坏的情况下,一次调用将针对零个元素,另一次针对 n-1 个元素,在最坏的情况下,对于每个递归级别,传递的内容的大小仅减少 1 个元素,时间复杂度为 O(n^2(。最好的情况是,如果枢轴最终位于中间,在每个递归级别上均匀拆分,或者对于时间复杂度 O(n log(n((接近均匀拆分。