what's the python之递归函数、二分算法与汉诺塔游戏

what's the 递归?

  递归函数的定义:在函数里能够再调用函数,若是这个调用的函数是函数自己,那么就造成了一个递归函数。算法

  递归的最大深度为997,这个是程序强制定义的,997彻底能够知足通常状况下用到递归的情形。数组

#最大997层
def foo(n): print(n) n += 1 foo(n) foo(1)

 

举个栗子:ide

  假设你想知道A的年龄,但你只知道A比B大2岁,B又比C大两岁,C又比D大两岁,D比E大两岁,刚好你知道E的岁数,那是否是就能知道A的岁数了呢,这就能够组成一个递归。那咱们假设E的岁数是20函数

def age(n): if n == 1: return 20
    else: return age(n-1)+2

print(age(5))

 

递归小练习优化

def func1(x):
    print(x)
    func1(x-1)

def func2(x):
    if x>0:
        print(x)
        func2(x-1)

def func3(x):
    if x>0:
        func3(x-1)
        print(x)
        
func1(5)    #死循环
func2(5)    #5 4 3 2 1
func3(5)    #1 2 3 4 5
练习1
def test(n):
    if n == 0:
        print("个人小鲤鱼", end='')
    else:
        print("抱着", end='')
        test(n-1)
        print("的我", end='')
def func(n):
    print('吓得我抱起了', end='')
    test(n)

func(3)#吓得我抱起了抱着抱着抱着个人小鲤鱼的个人个人我
练习2(吓得我抱起了抱着抱着抱着个人小鲤鱼的个人个人我)

 

二分算法

  递归函数的一个经典用法就是二分算法,二分算法的意思是用对半切查找的方式从由一群由小到大的数组成的列表中找到要找的数字的方法spa

举个栗子:3d

l = [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]
                                       #优化后的代码
def func(l,aim):                          def func(l, aim,start = 0,end = len(l)-1 ):                                 
    mid = (len(l)-1)//2                     mid = (start+end)//2
    if l:                                     if not l[start:end+1]:
        if aim > l[mid]:                       return
            func(l[mid+1:],aim)             elif aim > l[mid]:
        elif aim < l[mid]:                     return func(l,aim,mid+1,end)
            func(l[:mid],aim)               elif aim < l[mid]:
        elif aim == l[mid]:                   return func(l,aim,start,mid-1)
            print("bingo",mid)              elif aim == l[mid]:
    else:                                         print("bingo")
        print('找不到')                            return mid
func(l,66)                                index = func(l,68)
func(l,6)                                 print(index)

 

以上就是简单的二分算法,固然由于切片会形成内存的损耗,因此咱们还能够将以上代码进行改进code

def bin_search_rec(data_set,value,low,high):
    if low <= high:
        mid=(low+high) // 2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            return bin_search_rec(data_set,value,low,mid-1)
        else:
            return bin_search_rec(data_set,value,mid+1,high)
    else:return None

l = [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]
a=bin_search_rec(l,66,2,88) 
print(a)#2

 

汉诺塔游戏

  汉诺塔游戏是法国数学家爱德华·卢卡斯编写的一个印度的古老传说:大梵天创造世界的时候作了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。 大梵天命令婆罗门把圆盘从下面开始按大小顺序从新摆放在另外一根柱子上。 在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 64根柱子移动完毕之日,就是世界毁灭之时。blog

 

   这个游戏能够用递归的思想解决,首先咱们来捋一捋思路:递归

      两个盘子时:

      1. 把小圆盘从A移动到B
      2. 把大圆盘从A移动到C
      3. 把小圆盘从B移动到C

      n个盘子时:

      1. 把n-1个圆盘(除去最后一个之外的全部)从A通过C移动到B
      2. 把第n个圆盘(最后一个)从A移动到C
      3. 把n-1个小圆盘从B通过A移动到C

 接下来咱们来写代码

a=0
def hanoi(n,x,y,z):
    global a
    if n==1:
        a+=1
        print(x,'-->',z)
    else:
        hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上
        hanoi(1,x,y,z)#将最底下的最后一个盘子从x移动到z上
        hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上

n=int(input('请输入汉诺塔的层数:'))

hanoi(n,'柱子A','柱子B','柱子C')
print('一共用了%s次'%a)
"""
假设咱们的汉诺塔层数为3
请输入汉诺塔的层数:3
柱子A --> 柱子C
柱子A --> 柱子B
柱子C --> 柱子B
柱子A --> 柱子C
柱子B --> 柱子A
柱子B --> 柱子C
柱子A --> 柱子C
一共用了7次
"""

 

  汉诺塔移动次数的递推式:h(x)=2h(x-1)+1。h(64)=18446744073709551615 假设婆罗门每秒钟搬一个盘子,则总共须要5800亿年!因此世界是不会毁灭的哇咔咔~

相关文章
相关标签/搜索