问题描述
问题引入:
如何在数组中寻找最小的一个数字.有一种思路是:遍历一遍数组,数组元素进行对比大小.代码如下:
def order_last(arr):
min_value = arr[0]
for i in range(1,len(arr)):
if arr[i] < min_value:
min_value = arr[i]
return min_value
arr = [1,2,3,-1]
print(order_last(arr))
但是如果在数组中寻找第二小的元素呢?或者是第三小元素呢.
第一种思路
有一种思路是先对元素进行排序,使得数组下标与元素大小对应起来.
第一种思路的代码:
arr = [1,0,22,2,3,99]
def order_select_for_sort(arr,key):
return sorted(arr)[key-1]
print(order_select_for_sort(arr,2))
第二种思路
还有一种思路,采用分而治之的思路.递归求解出所要查找的元素.(需要事先理解快速排序的思路.)
具体描述:
p = 数组的起始点,
r = 数组的终点.
k = 要查找的第几小.(k=1就是第一小元素.)
q = pivot的下标,pivot的初始选择会是数组的最后一个值.之后遍历数组与pivot进行对比.小于piviot在pivot左边.大于piviot的在右边.
之后,会有三种情况
情况𝟏:𝒌 = 𝒒 − 𝒑 + 𝟏,𝑨[𝒒]为数组第𝒌小元素
情况𝟐:𝒌 < 𝒒 − 𝒑 + 𝟏,在𝑨[𝒑. . 𝒒 − 𝟏]中寻找第𝒌小元素
情况𝟑:𝒌 > 𝒒 − 𝒑 + 𝟏,在𝑨[𝒒 + 𝟏. . 𝒓]中寻找第𝒌 − (𝒒 − 𝒑 + 𝟏)小元素
如图.
第二种思路代码实现
arr = [1,0,22,2,3,99]
def order_select(arr,left,right,key):
# 这个是需要return
'''
key = k
left = p
right = r
pivot_index = q
'''
pivot_index = partition(arr,left,right) # q是主元的位置
if key == (pivot_index-left + 1):
x = arr[pivot_index]
elif key < (pivot_index-left + 1):
x = order_select(arr,left,pivot_index-1,key)
elif key>(pivot_index-left+1):
x = order_select(arr,pivot_index+1,right,pivot_index-left+1)
return x
def partition(array, l, r):
x = array[r] # 数组最后一个元素作为对比.
i = l - 1
for j in range(l, r):
if array[j] <= x:
i += 1
array[i], array[j] = array[j], array[i]
# print(array)
array[i + 1], array[r] = array[r], array[i+1]
return i + 1 # reture pivot_index
print(order_select(arr,0,len(arr)-1,2))
参考