【A-查找】1-有序数组二分法查找 递推和循环 python实现

版权声明:转载请声名出处,谢谢 https://blog.csdn.net/u010591976/article/details/82020979

二分查找:

前提:正序数列
例如:一个长度为n的正序数列,查找一个数 target是否在这个数列当中
(1)递归实现:
1-取数列正中间的数mid,
如果mid和x相等,则找到结果,查找成功 返回True
如果mid比x大,则x应该在mid的左侧,我们把mid左侧当作一个新的数列li
如果mid比x小,则x应该在mid的右侧,我们把mid右侧当作一个新的数列li
2-对于新的数列li 进行1的查找工作
3-一直重复上面查找,生成新的数列li为空的时候则 数列当中没有数x 返回False
(2)循环实现:
通过循环改变数组的start end mid位置处的索引,直到找到该元素。

时间复杂度:
最优O(1) 第一次取中间数mid 找到了 这种概率很低
最坏O(log n) 假设n个数的数列,每次把数列分成两半,n除以多少次2 等于1 呢? log n次

'''
Creat by HuangDandan
2018-08-24
[email protected]
'''

#递推法实现二分法查找
def dichotomyFind(a,target):                        #a数组,target查找的目标值
    n = len(a)
    mid = (n-1) >> 1
    flag = False
    if not a:                                       #细节1:每次递推a列表都是新的参数,需要对列表a进行判断
        return flag
    if a[mid] == target:
        flag = True
        return flag                                 #细节2:找到就立即返回,结束查找

    elif a[mid] > target:
        return dichotomyFind(a[:mid],target)        #细节3 return & mid-1
    else:
        return dichotomyFind(a[mid+1:], target)

'''
    #bug
    if not a:               #细节1:每次递推a列表都是新的参数,需要对列表a进行判断
        return flag
    if a[mid] == target:
        flag = True
        return flag    
    elif a[mid] > target:
        dichotomyFind(a[:mid],target)        #细节3 return
    else:
        dichotomyFind(a[mid+1:], target)
    return flag
'''

#循环实现二分法查找,通过循环改变索引值
def dichotomyFind2(a,target):
    start = 0
    end = len(a)-1

    flag = False                            #标记位
    while start <= end:
        mid = (start + end) >> 1

        if a[mid] == target:
            flag = True
            return flag
        elif a[mid] > target:
            start, end = 0, mid-1
        else:
            start, end = mid+1, end
    # 跳出循环说明没找到 返回标记位
    return flag




if __name__ == "__main__":
    Lst2 = [0, 1, 2, 3, 4, 6, 6]
    print(dichotomyFind2(Lst2,-1))

温故:
因为思想相同,循环和递归的时间复杂度是一样的。二分法递归的实现,每次都要开新的列表,实际上空间复杂度会更大

猜你喜欢

转载自blog.csdn.net/u010591976/article/details/82020979