线性时间选择

1、实现(平均T(n) = O(n),最坏T(n)=O(n 2))随机选择

随机数法
import random

def partition(a, left, right):
    i = left
    j = right
    key = a[left]
    while i < j:
        while a[j] >= key and i < j:
            j -= 1
        a[i] = a[j]
        while a[i] <= key and i < j:
            i += 1
        a[j] = a[i]
    a[i] = key
    return i


def randomized_partition(a, left, right):
    if left > right:   			# 为了保护randint函数的
        i = random.randint(left, right)
        a[i], a[left] = a[left], a[i]
    return partition(a, left, right)


def randomized_select(a, left, right, k):
    if left == right:
        return a[left]
    i = randomized_partition(a, left, right)
    j = i - left + 1
    if k <= j:
        return randomized_select(a, left, i, k)
    else:
        return randomized_select(a, i + 1, right, k)


number = random.randint(60, 80)
array = []
for i in range(0, number):
    array.append(random.randint(0, 2*number))
print("一共生成了" + str(number) + "个数")
print("他们是:")
print(array)
k = input("你要查找第几小的数字?")
print(randomized_select(array, 0, number - 1, int(k)))

2671c354764f4b548b1b67ead4237a7a.png

 

2、实现(最坏T(n)=O(n))中位数选择

中位数法
import random

def sort(a, l, r):           # 冒泡排序
    for i in range(l, r + 1):
        for j in reversed(range(i, r + 1)):
            if a[i] >= a[j]:
                a[i], a[j] = a[j], a[i]


def partition(a, left, right, x):     # 分区
    i = left
    j = right
    while i < j:
        while a[j] > x and i < j:
            j -= 1
        while a[i] < x and i < j:
            i += 1
        a[i], a[j] = a[j], a[i]
    return i


def find_mid(a, l, r):
    if r - l < 75:
        sort(a, l, r)
        return a[(l + r) // 2]
    else:
        b = []        # 存储中位数的数组
        i = l
        while True:
            if 5 * i + 4 <= r:         # 判断是否为最后一组
                sort(a, 5 * i, 5 * i + 4)
                b.append(a[5 * i + 2])
            else:
                sort(a, 5 * i, r)
                b.append(a[(5 * i + r) // 2])
                break
            i += 1
        return find_mid(b, 0, len(b) - 1)


def select(a, l, r, k):
    if r - l < 75:
        sort(a, l, r)
        return a[l + k - 1]
    else:
        mid_number = find_mid(a, l, r)
        mid_position = partition(a, l, r, mid_number)
        if k > mid_position:
            return select(a, mid_position + 1, r, k)
        else:
            return select(a, l, mid_position, k)


number = random.randint(150, 200)
array = []
for i in range(0, number):
    array.append(random.randint(0, number * 2))
print(array)
print("生成了" + str(number) + "个数")
k = input('输入想要第几小的数字')
print(select(array, 0, number - 1, int(k)))

f226062fc291465cb895488f7990bd19.png

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值