假设您使用C编程语言提供以下函数声明。
int partition(int a[], int n);
该函数将a[]
的第一个元素视为一个数据透镜并重新排列数组,以使小于或等于数据透视的所有元素都位于数组的左侧部分,并且所有大于该数组的元素都是在右边。此外,它移动枢轴,使枢轴是左侧部分的最后一个元素。返回值是左侧部分的元素数。
使用C编程语言中的以下部分给定函数来使用分区函数查找大小为n的数组a[]
中的第k个最小元素。我们假设k≤n
。
int kth_smallest (int a[], int n, int k)
{
int left_end = partition (a, n);
if (left_end+1==k) {
return a[left_end];
}
if (left_end+1 > k) {
return kth_smallest (___________);
} else {
return kth_smallest (___________);
}
}
缺少的参数列表分别为
(a, left_end, k)
和(a+left_end+1, n-left_end-1, k-left_end-1)
(a, left_end, k)
和(a, n-left_end-1, k-left_end-1)
(a, left_end+1, n-left_end-1, k-left_end-1)
和(a, left_end, k)
(a, n-left_end-1, k-left_end-1)
和(a, left_end, k)
我在这里找到关于" How to find the kth largest element in an unsorted array of length n in O(n)?"
的一个很好的解释我已阅读partition中使用的quick sort。答案是选项(1)。我同意答案。但我需要正式的解释。
你能解释一下吗?
编辑:AFAIK,分区算法将选定的枢轴放在正确的位置。我们需要递归分区算法来找到数组中的第k个最小元素。分区算法在数组的一侧运行,在它的左侧或右侧进行排序。我被困在这里。我在想,这取决于第k个索引号?
答案 0 :(得分:2)
简单。比如说,你选择了一个q th
最大的数组元素。在这种情况下,分区左半部分有q-1
个元素,右半部分有n-q
元素,而q th
元素是枢轴。现在,有三种可能性:
q
为k
,则会得到答案,即您的退货声明。q > k
,那么k th
元素位于数组的左半部分,而在左半部分,仍然是,{{1}最大的元素。因此,在分区中,我们传递数组的左半部分k th
,我们必须在那里找到k
最大的元素。k th
,那么,q < k
数组右半部分中的最大元素。此外,由于k th
个元素小于此右侧部分的最小元素,因此原始数组中的q
最大元素在右侧数组中最大k th
。因此,我们传递正确的数组k - q th
,以找到分区的最大元素k-q
。编辑:
为您的代码添加评论:
k-q th
现在,您的递归算法:
int partition(int a[], int n); //breaks array into 2 parts, according to pivot (1st element of array), left is smaller and right is larger han pivot.