第二次作业

一、找第k小数的分治算法

选基准元素:从数组中任选第一个元素a[left]作为基准(double x = a[left];)。

划分数组:partition函数通过双指针ij遍历,将数组划分为"小于基准"和"大于基准"两部分(因为快速选择的划分逻辑与快速排序一致,这里代码是"小于等于基准在前,大于基准在后")。

递归找第k小数:find函数中,通过rank = p - left + 1计算基准元素的"排名",然后根据rankk的大小关系,递归在左半部分(find(num, left, p - 1, k))或右半部分(find(num, p + 1, right, k - rank))查找。

二、时间复杂度

最好情况O(n):若每次partition选取的基准是当前数组的中位数,数组会被均匀划分,递归深度为 O(log n) ,每次划分操作是O(n) ,整体时间复杂度为 O( n )。例如,当数组是随机分布时,大概率触发此情况。

最坏情况O(n²):若每次partition选取的基准是数组的极值(如数组严格递增,每次选第一个元素为基准),则每次递归仅能排除一个元素,递归深度为O(n) ,每次划分操作是O(n) ,整体时间复杂度为O(n²) 。

三、分治法的分解、递归、合并

分解:partition函数将原数组问题分解为"左子数组"和"右子数组"的子问题;find函数通过判断rankk的关系,进一步确定子问题的范围。

递归:find函数自身调用(return find(...)),对分解后的子问题进行递归求解。

合并:这里的"合并"是通过基准元素的"排名"直接判断结果(if (rank == k) return num[p];),无需显式合并子数组,属于分治中"直接求解"的合并方式。