中位数和顺序统计量

在一个由n个元素组成的集合中,第i个顺序统计量是该集合中第i小的元素。例如,在一个集合中,最小值是第1个顺序统计量,最大值是第n个顺序统计量。用非形式化的描述来说,中位数是它所属集合的“中点元素”。

将求解顺序统计量的问题定义为如下选择问题:
输入:一个包含n个数的集合A和一个整数i1 \leq i \leq n
输出:元素x \in A,且A中恰好有i-1个其他元素小于它。

我们可以在\Theta(nlogn)的时间内解决这个问题,因为我们可以采用归并排序、堆排序或者随机化快速排序对输入数据进行排序,然后对排序好的集合输出第i个元素即可。

这里将采用更好时间复杂度\Theta(n)的方法解决这一问题。

我们借鉴随机化快速排序的方法,采用分治策略在集合中查找第i个顺序统计量

  • Devide
    和随机化快速排序相同,先将随机化主元放到正确的位置,如果该主元下标r=i,则输出主元结束程序运行。
  • Conquer
    如果i<r,则对主元的左侧子序列递归搜索;如果i>r,则对主元的左侧子序列递归搜索。
    最终将输出集合的第i个顺序统计量
  • Combine
    同随机化快速排序,这里不需要合并。

算法的Python3实现如下

import random

def partition(a, p, q):
    i = p
    for j in range(p+1, q):
        if a[j] < a[p]:
            i += 1
            a[i], a[j] = a[j], a[i]

    a[i], a[p] = a[p], a[i]
    return i

def randomized_select(a, p, q, i):
    if p > q:
        return
    r = partition(a, p, q)
    k = r - p + 1
    if i == k:
        return a[r]
    elif i < k:
        return randomized_select(a, p, r, i)
    elif i > k:
        return randomized_select(a, r+1, q, i-k)

if __name__ == '__main__':
    a = [4, 2, 3, 0, 1, 3, 2, 6]
    val = randomized_select(a, 0, len(a), 2)
    print(val)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容