教科书 Intro to Algorithms (CLRS) 的问题 9-3描述了一种快速 O(n) 算法,用于查找长度为 n 的数组的第 k 阶统计量(排序时数组中的第 k 个元素),对于特定的k 远小于 n 的情况。当 n 为奇数时,我不确定该算法的正确性,并希望找到一种方法来证明它是正确的。
基本思想是我们首先将数组分成两半,第一部分包含 floor(n/2) 个元素,第二部分包含 ceil(n/2) 个元素。然后,我们将前半部分的每个元素与后半部分的相应元素“配对”。当 n 为奇数时,这会留下一个剩余的未配对元素。
对于每一对合作伙伴,我们确保左合作伙伴 >= 右合作伙伴,如果不是,则交换两者。然后,递归地找到下半场的 k 阶统计量,将下半场进行的任何交换与上半场的相应交换镜像。之后,整个数组的k阶统计量要么在前半部分的前k个元素中,要么在后半部分的前k个元素中。
我的困惑来自数组长度 n 为奇数的情况,并且后半部分有一个单独的元素没有伙伴。由于递归是在后半部分执行的,由数组的最后一个 ceil(n/2) 元素组成,包括唯一的无伙伴最后一个元素,我们应该将下半部分进行的所有交换与相应的交换中的交换进行镜像上半场的合作伙伴,当其中一个交换涉及到最后的元素时,不清楚该怎么做,因为它没有合作伙伴。
教科书似乎没有特别注意这个问题,所以我假设当交换涉及到最后一个元素时,那么上半场就不要做任何镜像动作。结果,最后一个元素只是简单地“窃取”了与之交换的任何人的伙伴。但是,在这种情况下,是否有一种简单的方法可以查看算法是否仍然正确?如果当最后一个元素窃取了别人的伙伴时,伙伴实际上是第 k 阶统计量,然后被交换到一个无法访问的位置怎么办?涉及顺序统计选择的递归和分区机制对我来说足够不透明,因此我不能自信地排除这种情况。