python选择排序及其变体

import random

def randPartition(A:list,left:int,right:int)->int:
    temp = A[left]
    while left<right:
        while left<right and A[right]>temp:
            right -=1
        A[left] = A[right]
        while left<right and A[left]<=temp:
            left +=1
        A[right] = A[left]

    A[left] = temp
    return left


def quickSort(A:list,left:int,right:int)->int:
    """选择排序"""
    if left<right:
        pos = randPartition(A,left,right)
        quickSort(A,left,pos-1)
        quickSort(A,pos+1,right)


if __name__ == '__main__':
    A = [5,12,7,2,9,3]
    left,right = 0, len(A)-1
    quickSort(A,left,right)
    print(A)

使用选择排序的思想找第K大的数

def randSelect(A:list,left:int,right:int,k):
    """随机选取算法"""
    if left==right:
        return A[left]
    p = randPartition(A,left,right)
    M = p-left+1 # A[p]是第M大的数
    if k==M:
        return A[p]
    if k<M:
        return randSelect(A,left,p-1,k)
    else:
        return randSelect(A,p+1,right,k-M) # 在后面在找k-M个


if __name__ == '__main__':
    A = [5,12,7,2,9,3] # 第1大的数时12,第4大的数是5
    left,right = 0, len(A)-1
    k1=4
    ans = randSelect(A,left,right,len(A)+1-k1)
    print('ans:',ans)

使用选择排序的思想,实现: 

给定一个由整数组成的集合,将它分成2个子集合,使得这2个子集合的并为原集合,
交为空集,同时在2个子集合的元素个数n1和n2之差的绝对值|n1-n2|尽可能小的
前提下,要求它们各自的元素之和s1与s2之差的绝对值|s1-s2|尽可能大。求|s1-s2|

显然,只要找出第n/2大的数的位置,后面的和减去前面的和即可

"""
给定一个由整数组成的集合,将它分成2个子集合,使得这2个子集合的并为原集合,
交为空集,同时在2个子集合的元素个数n1和n2之差的绝对值|n1-n2|尽可能小的
前提下,要求它们各自的元素之和s1与s2之差的绝对值|s1-s2|尽可能大。求|s1-s2|
"""

def randSelect2(A:list,left:int,right:int,k):
    if left==right:
        return
    p = randPartition(A,left,right)
    M = p-left+1
    if M==k:
        return
    elif M>k: # k小,在前面找
        randSelect(A,left,p-1,k)
    else: # k大,在后面找
        randSelect(A,p+1,right,k-M)


if __name__ == '__main__':
    A = [1,6,33,18,4,0,10,5,12,7,2,9,3]
    left,right = 0, len(A)-1
    k1 = len(A)//2
    randSelect2(A,left,right,len(A)+1-k1)
    print(A)
    print("ans:",sum(A[len(A)//2:])-sum(A[:len(A)//2]))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值