给定n个元素,找出元素中的第二大元素。该问题如果用线性扫描的方法的话,
首先找出最大值,比较n-1次
然后从n-1个元素中找出最大值,比较n-2次
下面考虑设计一个选第二大元素的分治算法
1.将n个元素从中间一分为二
2.递归两个子问题,分别求出两个子问题的最大值,同时将被淘汰的较小元素记录在较大元素的列表中。在最大值的淘汰元素列表中找第二大元素。
实现
用字典存储被较大元素淘汰的元素,每个元素的key是给定的n个元素,value是一个列表,包括所有被该元素淘汰的元素
1.首先定义一个find_max()函数,实现第一阶段的操作:接收n个元素的列表a_list,要查找的问题的边界left和right。输出n个元素的最大值,同时将被淘汰的元素插入到字典相应key的value中
def find_max(arr,left,right):
global dic
if left>=right:
return arr[left]
mid=(left+right)//2
left_max=find_max(arr,left,mid)
right_max=find_max(arr,mid+1,right)
if left_max>right_max:
dic[left_max].append(right_max)
return left_max
else:
dic[right_max].append(left_max)
return right_max
2.定义find_max函数:接收最大值淘汰的元素列表,顺序查找列表中的最大值,即为n个元素的第二大元素
def find_second(n_max):
n=len(n_max)
second_max=n_max[0]
for i in range(1,n):
if n_max[i]>second_max:
second_max=n_max[i]
return second_max
arr=[6,12,3,7,2,18,90,87,54,23]
n=len(arr)
dic={}
for i in range(n):
dic.update([(a_list[i],[])])#初始化字典列表
first_max=find_max(a_list,0,n-1)
second_max=find_second(dic[first_max])
print(dic[first_max])
print(second_max)