分治法:關於選擇演算法,找最大,找最小,同時找最大和最小,找第二大
阿新 • • 發佈:2018-12-17
找最大或者最小,蠻力演算法為最優的演算法,需要比較n-1次
# 這個已經是最優的演算法了,比較n-1次
def findMax(arr):
max_pivot = arr[0]
for i in range(1,len(arr)):
if arr[i] > max_pivot:
max_pivot = arr[i]
return max_pivot
def findMin(arr):
min_pivot = arr[0]
for i in range(1,len(arr) ):
if arr[i] < min_pivot:
min_pivot = arr[i]
return min_pivot
還有一種分治的演算法,也是需要比較n-1次,類似於錦標賽,這裡比較次數就是淘汰掉的隊伍個數,劃分子問題的方法就是兩兩比較,只留最大,注意奇數的處理(直接晉級下輪)
# 兩兩比較得到最大的一半陣列
def partition_max(arr):
pointer = 0
max_arr =[]
while pointer <= len(arr)-2:
max_arr += [max(arr[pointer],arr[pointer+1])]
pointer +=2
# 假如是奇數,加上最後一個數,偶數的話加的為空
max_arr +=arr[pointer:]
return max_arr
# 找最大分治的寫法,也是最優的為比較n-1次
def findmax_recursive(arr):
if len(arr) == 1:
return arr[0]
max_arr = partition_max(arr)
return findmax_recursive( max_arr)
同時找最大和找最小,蠻力演算法,找最大n-1,找最小n-2,合計2n-3
使用分組的方式比較次數:3/2 *n -2
# 找最大和最小,得到最大一半分組和最小的一半分組
def partition_max_min(arr):
pointer = 0
max_arr =[]
min_arr =[]
while pointer <= len(arr)-2:
if arr[pointer] >=arr[pointer+1]:
max_arr.append(arr[pointer])
min_arr.append(arr[pointer+1])
else:
max_arr.append(arr[pointer+1])
min_arr.append(arr[pointer])
pointer +=2
max_arr +=arr[pointer:]
min_arr +=arr[pointer:]
return max_arr,min_arr
# 這個也是最優的演算法了
def findMaxMin(arr):
max_arr,min_arr = partition_max_min(arr)
min = findMin(min_arr)
max = findMax(max_arr)
return max,min
找第二大,蠻力演算法也是2n-3,採取錦標賽的方式冠軍比較n-1次,亞軍在冠軍的手下敗將裡產生比較logn-1次,這裡需要備忘冠軍的手下敗將,但是一開始冠軍不知道,所以每個選手需要記錄他曾經打敗過的選手
#%%
class node:
def __init__(self,value=None,miss=None):
self.value = value
self.miss =miss
def partition_max_with_nodes(arr):
pointer = 0
max_arr =[]
while pointer <= len(arr)-2:
if arr[pointer].value >=arr[pointer+1].value:
arr[pointer].miss.append(arr[pointer+1].value)
max_arr.append(arr[pointer])
else:
arr[pointer+1].miss.append(arr[pointer].value)
max_arr.append(arr[pointer+1])
pointer +=2
# 假如是奇數,加上最後一個數,偶數的話加的為空
max_arr +=arr[pointer:]
return max_arr
def findMaxSecondmax(arr):
arr_node =[]
for i in range(len(arr)):
arr_node.append(node(arr[i],[]))
def findmax_recursive(arr):
if len(arr) == 1:
return arr[0]
max_arr = partition_max_with_nodes(arr)
return findmax_recursive(max_arr)
pair = findmax_recursive(arr_node)
first_max = pair.value
second_max_arr = pair.miss
second_max = findMax(second_max_arr)
return first_max,second_max
arr = [4,44,5,77,8,32,18,99,377,55,33,11,12,999,678]
print(arr)
##print(findMax(arr))
##print(partition_max(arr))
##print(findmax_recursive(arr))
#print(partition_max_min(arr))
#print(findMaxMin(arr))
print(findMaxSecondmax(arr))
[4, 44, 5, 77, 8, 32, 18, 99, 377, 55, 33, 11, 12, 999, 678]
(999, 678)