次序选择问题(使用Python描述)

问题描述

问题引入:

如何在数组中寻找最小的一个数字.有一种思路是:遍历一遍数组,数组元素进行对比大小.代码如下:

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的在右边.

  • 之后,会有三种情况
    • 情况𝟏:𝒌 = 𝒒 − 𝒑 + 𝟏,𝑨[𝒒]为数组第𝒌小元素
    • 情况𝟐:𝒌 < 𝒒 − 𝒑 + 𝟏,在𝑨[𝒑. . 𝒒 − 𝟏]中寻找第𝒌小元素
    • 情况𝟑:𝒌 > 𝒒 − 𝒑 + 𝟏,在𝑨[𝒒 + 𝟏. . 𝒓]中寻找第𝒌 − (𝒒 − 𝒑 + 𝟏)小元素

如图.

img




第二种思路代码实现


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





参考

posted @ 2020-03-15 18:16  高坦的博客  阅读(432)  评论(0编辑  收藏  举报