递增数组将前几个元素依次挪到尾部--递增数组的旋转数组(部分有序,前后两部分分别有序)
考虑特殊:
1.数组为空
2.递增数组将前0个元素挪到尾部--完全有序,纯递增数组--最小值即为首元素
正常处理递增数组的旋转数组:
3.首尾元素相邻,时,最小值即为尾元素,跳出函数,返回最小值
1.数组中相邻某几个元素增量为0--b=[3,4,5,6,9,0,1,2,3,3]-可作为正常处理,依次缩小范围,直到3
2.数组中首、尾、中间值三者相同--【1,1,1,0,1】,部分有序已经打乱了,无法判断该缩小范围至那部分,改用顺序查找
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 18 10:27:53 2017
@author: zzpp220
"""
'''二分查找适合一个 已经全部排序(或部分排序)的数组中,查找数字或统计数字出现的次数'''
classMin_Rotate:
def __init__(self,array):
self.array=array
defFind_Min(self):
ifnot self.array:
returnNone
first_index=0
last_index=len(self.array)-1
##看首尾大小,满足条件的话,确定是旋转数组(首>=尾)
while self.array[first_index]>=self.array[last_index]:
##采用二分法进行查找
mid_index=(first_index+last_index)/2
##跳出该循环的条件,当层层缩小后last_index,first_index为相邻元素时,则last为最小(旋转了)
if last_index-first_index==1:
return self.array[last_index]
##首尾和中间元素全相等,情况特殊(首=中=尾),已经不满足排序的条件(不管是全部还是部分)只能改用顺序查找,该函数直接返回顺序查找的结果
if self.array[last_index]==self.array[first_index]and self.array[mid_index]==self.array[first_index]:
return self.Min_Inorder()#(first_index,last_index)
##除去上面的特殊情况,判断中间元素与首、尾元素的关系,看要缩小至哪一半范围,循环如此
#如果中间值大于首值,说明处于前面的递增序列,则最小值在中间值的后面,选择后半部分继续查找
if self.array[mid_index]>=self.array[first_index]:
first_index=mid_index
#如果中间值小于尾值,说明处于后面的递增序列,则最小值要么为中间值,要么比中间值还小在中间值的前面,选择前半部分继续查找
elif self.array[mid_index]<=self.array[last_index]:
last_index=mid_index
##首尾元素大小不满足,说明首小于尾,升序(即把递增数组的前0个元素搬到后面去了)是特例,首元素为最小
return self.array[first_index]
##顺序查找,基于递增序列旋转数组的特点,首个小于value的值即为最小值。如一直没有,则说明最小值即为value
defMin_Inorder(self):
value=self.array[0]
return[self.array[i]for i in range(1,len(self.array)-1)if self.array[i]< value]
return value
#==============================================================================
# def Min_Inorder(self,first_index,last_index):
# value=self.array[first_index]
# return [self.array[i] for i in range(first_index+1,last_index) if self.array[i] < value]
# return value
#==============================================================================
a=[3]
b=[3,4,5,6,9,0,1,2,3,3]
c=[1,1,1,1,0,1,1,1]
d=[2,3,6,8,9,12]
e=[5,6,7,2,4,5,5]
f=None
solution=Min_Rotate(b)
print solution.Find_Min()
程序中独立出的Min_Inorder 也可以直接放到主程序中,反正就几句话。见附件。