1 #使用实例:使用二分法查找数列中有没有66,并返回其索引。
2 num_li = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]3
4 #没接触二分法之前,我们大概会用for循环遍历数列,判断其中元素是否是66,如果是返回其索引!
5 #但是,想一想,如果此数列有几百万个元素,这样遍历会很慢,如何查找最快?答案是:二分法
6 #第一次,找到数列最中间的元素,比较它和66的大小,如果大于66,就说明66在它前面,前面的数又组成一个数列num_li_new_1,
7 #如果它比66小,则说明66在它的后面,将其后面的数,组成一个新的数列:num_li_new_2
8 #第二次,在num_li_new_1或者num_li_new_2中,继续按照第一的方法寻找下去。。。。。。
9 #第n次,如果有该元素,一定会找到它,而且只有一个元素了!
10
11 #1)、第一次尝试用二分法
12 deffind_num(list, target):13 mid_index = len(list)//2
14 if list[mid_index] ==target:15 print('Congratunation! You get it!')16 returnmid_index17 elif list[mid_index] >target:18 new_list =list[:mid_index]19 find_num(new_list, target)20 else:21 new_list = list[mid_index + 1:]22 find_num(new_list, target)23
24 res = find_num(num_li, 67)25 print(res)26
27 #惊奇的发现,打印的结果是:None
28 #分析未得到预想结果的原因: todo:没有接收返回值,也没有返回任何值! 所以为None
29 def find_num(list, target): #第一步:list=num_li target = 67
30 mid_index = len(list) // 2 #第二步:mid_index = 24//2 = 12
31 if list[mid_index] == target: #list[mid_index] = list[12] = 41
32 print('Congratunation! You get it!')33 returnmid_index34 elif list[ mid_index ] >target:35 new_list =list[ :mid_index ]36 find_num(new_list, target)37 else: #第三步:41 < 67
38 new_list = list[ mid_index + 1: ] #第四步:new_list = list[13:] = [42,43,55,56,66,67,69,72,76,82,83,88]
39 find_num(new_list, target) #第五步:find_num(new_list, 67)todo:没有接收返回值,也没有返回任何值!
40
41 def find_num(list, target): #第六步:list=new_list target = 67
42 mid_index = len(list) // 2 #第七步:mid_index = 12//2 = 6
43 if list[mid_index] == target: #list[mid_index] = list[6] = 69
44 print('Congratunation! You get it!')45 returnmid_index46 elif list[ mid_index ] > target: #第八步:69 > 67
47 new_list = list[ :mid_index ] #第九步:new_list = list[:6] = [42,43,55,56,66,67]
48 find_num(new_list, target) #第十步:find_num(new_list, 67) todo:没有接收返回值,也没有返回任何值!
49 else:50 new_list = list[ mid_index + 1: ] #51 find_num(new_list, target) #52
53 def find_num(list, target): #第十一步:list=new_list target = 67
54 mid_index = len(list) // 2 #第十二步:mid_index = 6//2 = 3
55 if list[mid_index] == target: #list[mid_index] = list[3] = 56
56 print('Congratunation! You get it!')57 returnmid_index58 elif list[ mid_index ] > target: #59 new_list =list[ :mid_index ]60 find_num(new_list, target) #第十步:find_num(new_list, 67)
61 else: #第十三步:56 < 67
62 new_list = list[mid_index + 1:] #第十四步:new_list = list[4:] = [66,67]
63 find_num(new_list, target) #第十五步: find_num(new_list, 67) todo:没有接收返回值,也没有返回任何值!
64
65 def find_num(list, target): #第十六步: list=new_list target = 67
66 mid_index = len(list)//2 #第十七步:mid_index = 2//2 = 1
67 if list[mid_index] == target: #第十八步:list[mid_index] = list[1] = 67 正好相等!
68 print('Congratunation! You get it!') #第十九步:输出Congratunation! You get it!
69 return mid_index #第二十步:将mid_index = 1 todo 返回给调用该函数的地方:即第十五步
70 elif list[mid_index] >target:71 new_list =list[:mid_index]72 find_num(new_list, target)73 else:74 new_list = list[mid_index + 1:]75 find_num(new_list, target)76
77 #2)、第二次尝试用二分法
78
79 deffind_num(list, target):80 mid_index = len(list)//2
81 if list[mid_index] ==target:82 print('Congratunation! You get it!')83 returnmid_index84 elif list[mid_index] >target:85 new_list =list[:mid_index]86 returnfind_num(new_list, target)87 else:88 new_list = list[mid_index + 1:]89 returnfind_num(new_list, target)90
91 res = find_num(num_li, 67)92 print(res)93
94 #继续惊奇的发现,结果是:0,这并不是我们预想的结果!
95 #原因分析:索引乱了,我们切分数列后,用的是新的索引!
96
97 #3)、第三次尝试用二分法
98
99 #def find_num(list, target, start = 0, end = len(list)): #TypeError: object of type 'type' has no len()
100 def find_num(list, target, start = 0, end =None):101 end = len(list) if end is None elseend102 #mid_index = len(list)//2 # 有时会报错:IndexError: list index out of range
103 mid_index = (end - start)//2 + start #104 if list[mid_index] <105 list mid_index>
106 return find_num(list, target, start=mid_index + 1, end=end)107 elif list[mid_index] >target:108 #new_list = list[start:mid_index]
109 return find_num(list, target, start=start, end=mid_index)110 else:111 print('Congratunation! You get it!')112 returnmid_index113
114 res = find_num(num_li, 66)115 print(res)116
117 #结果是出现了,还发现一个问题,如果查找的数不在列表中,会报错:RecursionError: maximum recursion depth exceeded in comparison
118
119 #4、第四次
120 def find_num(list, target, start = 0, end =None):121 end = len(list) if end is None elseend122 if end >start:123 mid_index = (end - start)//2 + start #124 if list[mid_index] <125 return find_num target start="mid_index" end="end)126" elif list>target:127 return find_num(list, target, start=start, end=mid_index)128 else:129 print('Congratunation! You get it!')130 returnmid_index131 else:132 return '该数列中没有你找的数!'125>
133
134 res = find_num(num_li, 44)135 print(res)
105>