DAY 006--查找某个值是否在列表中(二分法)

005 题目如下:                                        

1、给定一个num_list= [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

2、根据用户输入的值,判断是否在num_list中

流程分析:                                                                    

1、编写一个查找函数,运用二分法+递归思想:

  • 1.1、先定义好列表的位置:
    • lower=0:序列的起始值)
    • high=len(lst)-1:序列最后一个元素的索引值
    • middle=(lower+high)//2
  • 1.2、从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
  • 1.3、如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找(运用函数递归的思想),而且跟开始一样从中间元素开始比较。
  • 1.4、如果在某一步骤数组为空,则代表找不到。

2、如何运用函数递归的思想?

  • 2.1、如果value>lst[middle],说明函数应该去列表的后1/2去找:return func(list[middle+1:],value)
  • 2.2、如果value<lst[middle],说明函数应该去列表的前1/2去找:return func(list[:middle-1],value)

3、如果找到了值,返回True,如果没有找到,返回False

代码分析:                                                                     

def binary_search_loop(lst,value):
    low, high = 0, len(lst)-1
    while low <= high:
        mid = (low + high) // 2
        if lst[mid] < value:
            lst=lst[mid+1:]
            return binary_search_loop(lst,value)
        elif lst[mid] > value:
            lst = lst[:mid]
            return binary_search_loop(lst, value)
        else:
            return True
    return False


number_list = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

def main():
    while True:
        num=input(">>:").strip()
        try:
            num=int(num)
        except:
            raise TypeError("请输入数字")
        if binary_search_loop(number_list,num):
            print("%d存在列表中"%num)
        else:
            print("该值不存在")
if __name__=="__main__":
    main()

方法二流程分析:                                                           

1、编写一个查找函数,运用二分法+循环思想:

  • 1.1、先定义好列表的位置:
    • lower=0:序列的起始值)
    • high=len(lst)-1:序列最后一个元素的索引值
    • middle=(lower+high)//2
  • 1.2、从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;
  • 1.3、如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找(运用循环的思想),而且跟开始一样从中间元素开始比较。
  • 1.4、如果在某一步骤数组为空,则代表找不到。

2、如何运用循环的思想?

  • 2.1、如果value>lst[middle],说明函数应该去列表的后1/2去找:lower=middle+1
  • 2.2、如果value<lst[middle],说明函数应该去列表的前1/2去找:high=middle-1

2、如果找到了值,返回True,如果没有找到,返回False

方法二代码:                                                                 

def binary_search_loop(lst,value):
    low, high = 0, len(lst)-1
    while low <= high:
        mid = (low + high) // 2
        if lst[mid] < value:
            low = mid + 1
        elif lst[mid] > value:
            high = mid-1
        else:
            return True
    return False


number_list = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

def main():
    while True:
        num=input(">>:").strip()
        try:
            num=int(num)
        except:
            raise TypeError("请输入数字")
        if binary_search_loop(number_list,num):
            print("%d存在列表中"%num)
        else:
            print("该值不存在")
if __name__=="__main__":
    main()

 

题目反思:                                                                    

1、本题还可以用for循环查找的,但是使用for循环容易造成查找速度慢,如果数据量过大,for循环肯定不能使用

2、在使用二分法+递归中,要考虑到

  • lower==high,也就是列表在二分法后只剩一个元素的情况,
  • 然后去判断这个元素是不是等于输入的值,如果不是则返回False

3、我做题过程中的BUG主要有两个:

  • 第一个是第 2 点
  • 第二个是没有考虑到 num_list[middle]=num 的情况

4、在搜寻资料中,还看见了二分法循环实现,然后自己照着二分法+循环的方法实现了本题,根据程序的运行,发现二分法循环更加节约查询的时间。

5、关于二分法循环和二分法递归的方法更多详细比较,在算法思想的第一篇,欢迎观阅!

新学知识点:                                                                 

1、二分法概念

2、二分法实现方法:递归、循环

3、又一次使用了递归,加深了一点对递归的理解

4、二分法+循环是很好的解题思想,记住这道题!

Mark on 2018.04.09

原文地址:https://www.cnblogs.com/JunSheep/p/8743074.html