递归
- 1. 递归
- 1.1 基线条件和递归条件
- 2. 栈
- 2.1 调用栈
- 2.2 递归调用栈
1. 递归
循环和递归可以实现相同的功能,如:
- 循环
def look_for_key(main_box)pile = main_box.make_a_pile_to_look_thorugh()while pile is not empty:box = pile.grab_a_box()for item in box:if item.is_a_box():pile.append(item)elif item.is_a_key():print "find the key!"
- 递归
def look_for_key(box)for item in box:if item.is_a_box():look_for_key(item)elif item.is_a_key():print "find the key!"
如果使用循环,程序的性能可能更高;如果使用递归,程序可能更容易理解。
1.1 基线条件和递归条件
编写递归函数时,必须告诉它何时停止递归。因此,每个递归函数都有两个部分:基线条件和递归条件。递归条件指的时函数调用自身,而基线条件指的是函数不调用自己,从而避免形成无限循环。
def countdown(i)print iif i < 1: //基线条件returnelse //递归条件countdown(i)
2. 栈
栈是一种简单的数据结构。
数据存储和读取特点是:“先进后出”。
具备两种操作:压入(插入)和弹出(删除并读取)。
2.1 调用栈
计算机在内部使用被称为调用栈的栈。
当在一个函数中调用多个另外的函数时:调用另一个函数时,当前函数暂定并处于未完成状态。只有先执行完调用函数,再回到当前函数进行执行。
计算机使用一个栈来表示函数的内存块(调用函数时,函数调用涉及的所有变量的指存储在内存中)。
栈用于存储多个函数的变量,被称为调用栈。
2.2 递归调用栈
def fact(x)if x == 1: //基线条件return 1else //递归条件return fact(x-1)*x
每个fact(x)调用都有自己的x变量。在一个函数调用中不能访问另一个的x变量。
使用栈虽然很方便,但是也是需要付出代价:存储详尽的信息可能占用大量的内存。每个函数调用都要占用一定的内存,如果栈很高,就意味着计算机存储了大量函数调用的信息。此时可以选择:重新编写代码,转而使用循环;使用尾递归。