赞
踩
目录
什么是递归?递归就是方法自己调用自己。比如下面这个例子
def fun(n): print(n) fun(n-1)if __name__ == '__main__': fun(10)
它就是个递归函数,但是你会发现它会一直运行下去
109876.....
但这样就会导致很多错误,我想没人会要一个无线循环的函数吧,所以我们需要有跳出循环的条件,正因为如此,每个递归函数有两部分:基线条件(让函数知道何时停止调用)和递归条件(函数调用自己),比如我们给上面的函数添加基线条件
def fun(n): print(n) if n<8: return else: fun(n-1)if __name__ == '__main__': fun(10)
运行结果:
10987
这样这个函数就变得合理了。
但在调用递归函数的时候得注意递归的深度,用python编写递归函数,它的默认最大递归深度为1000,如果递归数超过这个量了,出来的值就可能不对,比如这个题
- def funb(n): if n>=1: return 1/n*funb(n-1) else: return 1def func(k): e=0 for i in range(1,k+1): e+=funb(i) return eif __name__ == '__main__': k=int(input('>5的正整数k
- ')) x=func(k) print('%.10f'%x)
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
简单来说,栈就是一种只能在表尾进行插入和删除操作的线性表。
它按照后进先出的原则存储数据。
压入(插入)和弹出(删除并读取)
计算机内部使用的栈称为调用栈。
调用栈最经常被用于存放子程序的返回地址。在调用任何子程序时,主程序都必须暂存子程序运行完毕后应该返回到的地址。因此,如果被调用的子程序还要调用其他的子程序,其自身的返回地址就必须存入调用栈,在其自身运行完毕后再行取回。在递归程序中,每一层次递归都必须在调用栈上增加一条地址,因此如果程序出现无限递归(或仅仅是过多的递归层次),调用栈就会产生栈溢出。
调用栈的主要功能是存放返回地址。除此之外,调用栈还用于存放:
本地变量:子程序的变量可以存入调用栈,这样可以达到不同子程序间变量分离开的作用。
环境传递:有些语言(如Pascal与Ada)支持“多层子程序”,即子程序中可以利用主程序的本地变量。这些变量可以通过调用栈传入子程序。
如下面这个函数
def fun1(name): print('hello',name) fun2(name) print('hi',name) fun3()def fun2(name): print('==',name,'==')def fun3(): print('hello python')if __name__ == '__main__': fun1('tutu')
运行结果:
hello tutu== tutu ==hi tutuhello python
它的栈的调用过程大概为这样
当我们调用fun2的时候你会发现fun1只执行了一部分,即当我们调用另外一个函数时,当前函数暂停并处于未完成状态,就是当前函数挂起了,此时该函数的所有变量都在内存中。
同时递归函数也使用调用栈
如下面这个计算阶乘的函数
def fun(n): if n==1: return 1 else: return n*fun(n-1)if __name__ == '__main__': print(fun(3))
运行结果:
6
栈具有的操作:
Stack() 创建一个新的空栈
push(item) 添加一个新的元素item到栈顶
pop() 弹出栈顶元素
peek() 返回栈顶元素
is_empty() 判断栈是否为空
size() 返回栈的元素个数
class Stack(): """"创建一个栈""" def __init__(self): self.items=[] """判断是否为空""" def is_empty(self): return self.items==[] """添加一个新的元素到栈顶""" def push(self,item): self.items.append(item) """弹出栈顶元素""" def pop(self): self.items.pop() """返回栈顶元素""" def peek(self): return self.items[len(self.items)-1] """返回栈的元素个数""" def size(self): return len(self.items)if __name__ == '__main__': s=Stack() # 判读栈是否为空 print(s.is_empty()) # 压入三个元素 s.push(1) s.push(2) s.push(3) print(s.items) # 弹出 s.pop() print(s.items) # 返回栈顶元素 print(s.peek()) # 返回栈的元素个数 print(s.size())
运行结果:
True[1, 2, 3][1, 2]22
虽然使用栈很方便,但是也有缺点,每个函数的调用有需要占用一定的内存,如果栈很高,就意味着计算机存储了大量的函数调用信息,会耗费大量的内存,这时候大家可以考虑使用循环。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。