算法导论 第九章 中位数和顺序统计量

def:第i个顺序统计量,是该集合中第i小的元素。

def:选择问题:输入,一个包含n个数的集合A,和一个整数i, 1<=i<=n。输出,元素x属于A,且A中恰好有i-1个其他元素小于它。


9.1 最大值和最小值

寻找一个数组中的最大值和最小值需要经过n-1次比较找到

def MINIMUM(A):
    mini = A[0]
    for i in range(1, len(A)):
        if mini > A[i]:
            mini = A[i]
    return mini

def MAXIMUM(A):
    maxi = A[0]
    for i in range(1, len(A)):
        if maxi < A[i]:
            maxi = A[i]
    return maxi
而同时寻找最大值与最小值则可以通过同时取两个数进行比较得到3*(n//2)次比较得到

def MINIMUM_MAXIMUM(A):
    n = len(A)
    start = 0
    if n % 2 == 0:
        start = 2
        S = A[ : start]
        mini = MINIMUM(S)
        maxi = MAXIMUM(S)
        
    else:    
        start = 3
        S = A[ : start]
        mini = MINIMUM(S)
        maxi = MAXIMUM(S)

    for i in range(start, len(A), 2):
        if A[i] > A[i + 1]:
            mn = A[i + 1]
            mx = A[i]
        else:
            mn = A[i]
            mx = A[i + 1]

        if mn < mini:
            mini = mn
        
        if mx > maxi:
            maxi = mx

    return mini, maxi


9.2 期望为线性时间的选择算法

期望为线性时间的选择算法,利用parttion将数组分组,最坏情况为n^2,期望运行时间为n

def PARTITION(A, p, r):  
    x = A[r]  
    i = p  
    for j in range(p, r):  
        if A[j] <= x:  
            temp = A[i]  
            A[i] = A[j]  
            A[j] = temp  
            i = i + 1  
  
    temp = A[i]  
    A[i] = A[r]  
    A[r] = temp  
  
    return i  

def RANDOMIZED_PARTITION(A, p, r):  
    i = random.randint(p, r)  
    temp = A[i]  
    A[i] = A[r]  
    A[r] = temp  
    return PARTITION(A, p, r)

def RANDOMIZED_SELECT(A, p, r, i):
    if p == r:
        return A[p]
    q = RANDOMIZED_PARTITION(A, p, r)
    k = q-p+1
    if i == k:
        return A[q]
    elif i < k:
        return RANDOMIZED_SELECT(A, p, q-1, i)
    else:
        return RANDOMIZED_SELECT(A, q+1, r, i-k)
算法效率的证明过程与快速排序一样,利用随机变量指示器证明其期望运行时间。

9.3 最坏情况为线性时间的选择算法

找到数组的第k位数,然后根据这个数对数组做划分,再在相对应的子数组中寻找第i位数。有T(n) = T(n) + T(max(k, n-k)) + O(n),T(n) = T(n) and T(n) >= T(max(k, n-k))。所有问题的关键在于缩小问题的规模使得等式右边的第一个T(n)变为T(x),x<n,且取得k划分使得T(n) > T(x) + T(max(k, n-k)) + O(n),


def PARTITION_BYVALUE(A, p, r, value):
    flag = p
    i = p  
    for j in range(p, r+1):  
        if A[j] <= value:  
            temp = A[i] 
            A[i] = A[j]
            A[j] = temp
            if A[i] == value:
                flag = i
            i = i + 1
    if i > flag:
        temp = A[i-1]  
        A[i-1] = A[flag]  
        A[flag] = temp
  
    return i-1

def INSERTION_SORT(A): 
    for j in range(1, len(A)):
        key = A[j]
        i = j - 1
        while i >= 0 and A[i] > key:
            A[i + 1] = A[i] 
            i = i - 1
        A[i + 1] = key

def SELECT(A, p, r, i):
    if p == r:
        return A[p]
    B = []
    midarray = []
    for j in range(p, r+1, 5):
        if j+5 > r:
            B.append(A[j:r+1])
        else:
            B.append(A[j:j+5])
        
        INSERTION_SORT(B[len(B)-1])
        midarray.append(B[len(B)-1][len(B[len(B)-1])//2])
        
    mid = SELECT(midarray, 0, len(midarray)-1, len(midarray)//2)
    q = PARTITION_BYVALUE(A, p, r, mid)
    assert(A[q] == mid)
    k = q-p+1
    if i == k:
        return A[q]
    elif i < k:
        return SELECT(A, p, q-1, i)
    else:
        return SELECT(A, q+1, r, i-k)




习题解答

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值