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]))