我是c ++的新手,并通过http://geeksquiz.com/quick-sort/
的快速排序算法以下是代码片段,我无法理解为什么低和高的值会发生变化
int partition (int arr[], int low, int high)
{
int pivot = arr[high]; // pivot
int i = (low - 1); // Index of smaller element
for (int j = low; j <= high- 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++; // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}
/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low --> Starting index,
high --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);
// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
请帮助我理解上述逻辑。
答案 0 :(得分:3)
找一个分区。 partition
的后置条件是枢轴元素左侧的所有内容都小于或等于分区中的元素,并且枢轴元素右侧的所有内容都将大于或等于枢轴元素。递归左右子阵。
通过循环不变量,您将拥有一个已排序的数组。
为简单起见,我们假设您的分区始终返回中间元素。
你知道partition
的帖子条件确保左边最多是枢轴元素,右边至少是枢轴元素。
现在通过递归调用low == low
和high == pi - 1
的快速排序来递归排序左侧。 pi
位于正确的空间内,因此您不必担心这一点。最后,您使用low == pi+1
和high == high
在右侧数组上调用quicksort。
重复直到所有内容都已排序(即!(low < high)
)。
在此图中很好地解释了递归任务(我们假设每次都是pivot的中间元素)。这也方便地显示了O(n log n)
时间复杂度的平均值。
答案 1 :(得分:2)
您已经澄清了您的问题,即您了解partition()背后的逻辑,而不是递归。确定。
您必须从假设开始,而quickSort()
将对您的数组进行排序。接受它作为给定。公理。一定是真的。您可以确信quickSort()
将对您的阵列进行排序。作为一个起点,你必须接受这个陈述作为一个无可置疑的事实。
然后,您已经了解partition()
将列表分为两半。基于此,您可以得出以下结论:
在pivoting元素之前的数组的一半只包含小于pivot元素的值。
pivoting元素之后的数组的一半只包含大于pivot元素的值。
1&amp; 2是partition()
操作的结果,您表示您完全理解。鉴于1&amp; 2,作为一个起点,你可以得出结论,如果在1和1中引用的数组的一半。 2完全自我排序,整个数组必须完全排序。
你如何制作1&amp; 2真的吗?好吧,你递归地应用quickSort()
算法。您刚才同意quickSort()
将对其获得的数组进行完全排序。因此,在quickSort()
递归排序两半之后,最终结果必须是完全排序的列表。
Q.E.D。
P.S。上面使用的术语“阵列的一半”是一个松散使用的术语。当然,阵列的每一半的实际大小不会是原始阵列的一半。这对整体逻辑没有影响。