特点
递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1) 递归就是在过程或函数里调用自身。
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
要求
递归算法所体现的“重复”一般有三个要求:
一是每次调用在规模上都有所缩小(通常是减半);
二是相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
三是在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。
实现
1. 通过递归实现2分查找
现有列表 primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97], 要求尔等 用最快的方式 找出23 。 请Low B, Low 2B ,Low 3B 三个同学来回答这个问题。
Low B: 这个很简单,直接用 if 41 in primes:print("found it!") , 话音未落就被老师打了,让你自己实现,不是让你用现成提供的功能, Low B于是说,那只能从头开始一个个数了,然后Low B被 开除了。。。
Low 2B: 因为这个列表是有序的, 我可以把列表从中截取一半,大概如下:
p1 = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,41]
p2 = [ 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
然后看p1[-1]也就是41是否比23大, 如果比23大就代表23肯定在p1里面,否则那就肯定在p2里面。现在我们知道23比41小,所以23肯定在p1里,但p1里依然有很多元素, 怎么找到23呢?很简单,依然按上一次的方法,把p1分成2部分,如下:
p1_a = [2, 3, 5, 7, 11, 13,17]
p1_b = [19, 23, 29, 31, 37,41]
然后我们发现,23 比p1_a最后一个值 17 大,那代表23肯定在p1_b中, p1_b中依然有很多元素,那就再按之前的方法继续分半,最终用不了几次,肯定就把23找出来了!
说完,Low 2B满有成就感的甩了下头上的头皮屑。
老师:很好,确实较Low B的方案强很多。 然后转头问Low 3B ,你有更好的想法 么?
Low 3B: 啊。。。噢 ,我。。。我跟Low 2B的想法一样,结果被他说了。
老师:噢,那你帮我把代码写出来吧。
Low 3B此时冷汗直冒,因为他根本没思路,但还是硬着头皮去写了。。。。虽然自己没思路,但是会谷歌呀,三个小时过去了,终于憋出了以下代码:
def binary_search(data_list,find_num): mid_pos = int(len(data_list) /2 ) #find the middle position of the list mid_val = data_list[mid_pos] # get the value by it's position print(data_list) if len(data_list) >1: if mid_val > find_num: # means the find_num is in left hand of mid_val print("[%s] should be in left of [%s]" %(find_num,mid_val)) binary_search(data_list[:mid_pos],find_num) elif mid_val < find_num: # means the find_num is in the right hand of mid_val print("[%s] should be in right of [%s]" %(find_num,mid_val)) binary_search(data_list[mid_pos:],find_num) else: # means the mid_val == find_num print("Find ", find_num) else: print("cannot find [%s] in data_list" %find_num) if __name__ == '__main__': primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] binary_search(primes,67)