python数据结构与算法-递归Recursion

python数据结构与算法-递归

  • 1.什么是递归
  • 2.递归三要素
  • 3.将整数转换为任意进制表示的字符串形式
  • 4.栈帧:实现递归

1.什么是递归

递归是一种解决问题的方法,他会把一个复杂的问题分解为越来越小的子问题,直到问题变得非常容易解决。
举个栗子:计算列表[1,3,5,7,9]的和
你肯定首先会想到使用一个for循环或者while循环,将列表中的所有元素累加求和,没错,这种方法可以!但是你可以利用递归的思想解决这个问题吗?
回归问题本身,让我们来分析列表求和:sum=1+3+5+7+9,还可以用什么方法表示?加法计算是两个数字相加,同理可得sum=(1+(3+(5+(7+9)))),换个括号方向也可以写成sum=((((1+3)+5)+7)+9),基于上述思想,我们可以看到是不用任何循环的思想就可以计算求和问题,用代码表示:

def sum(num_list):
	if len(num_list) == 1:
		return num_list[0]
	else:
		return num_list[0]+sum(num_list[1:])

他的递归过程如下图所示:
python数据结构与算法-递归Recursion_第1张图片

是不是非常amazing?在第五行函数调用了自身!这就是递归函数,他是一种调用自身的函数。

2.递归三要素

1.要有基本结束条件;
2.所有得操作必须改变自己的状态并朝基本结束条件演近;
3.必须递归的调用函数自身。

还是以上述求和为例,len(num_list)=1就是基本结束条件,sum(num_list[1:])就是朝基本结束条件逼近,num_list[0]+sum(num_list[1:])就是调用了函数自身。

3.将整数转换为任意进制表示的字符串形式

假设将一个十进制的整数10转换为十进制的字符串“10”或者转为二进制的字符串“1010”,用递归的思想在程序中如何实现?
下面我们讨论将十进制的769转换为任意进制的字符串,我们假设有一个字符串str1=“0123456789”,那么只要是小于10的整数都可以用字符串表示出来,例如9可以表示为str1[9]。我们可以将7,6,9拆成三个单独的数字,其中任一个数字都可以用字符串str1表示。
据上述分析确定进位数后,整个算法包含3部分:
1.将原始整数分解为一连串的单个数字;
2.通过在字符串中检索将单个数字转换为字符串;
3.将这些单个字符串连接起来,形成最终的结果。
对应到实际数学思想中,我们参考整数的除法取余思想,769除以10等于76余9,76再除以10等于7余6,7除以10等于0余7,将所有余数组合起来就是769.用代码将769转换为16进制表示出来,如下:

def to_str(num,base):
	str1="0123456789ABCDEF" 
	if num<base:
		return str1[num]
	else:
		return to_str(num/base,base)+str1[num%base]

整数转换为10进制的递归过程如下图所示:
python数据结构与算法-递归Recursion_第2张图片
在上图中看起来生成的结果好像顺序错了,从上到下是967,不是769。兄弟,这样理解是错的,回顾下“栈”的相关知识,我们上述代码的第6行是先递归调用,然后添加字符串,所以生成的字符串还是769!

练习:
写一个函数,接受一个字符串为参数,返回一个反向的新字符串。

def unorder(str1):
	if len(str1) == 1:
		return str1[0]
	else:
		return str1[-1]+unorder(str1[:-2])

4.栈帧:实现递归

还是实现将一个整数转换为任意进制的问题:
首先写一个类,并将其实例化(否则不方便使用栈的方法):

class Stack:
	def __init__(self):
		self.items=[]
	def isEmpty(self):
		return self.items == 0
	def push(self,item):
		self.items.append(item)
	def pop(self):
		return self.items.pop()
	def size(self):
		return len(sel.items)
Stack=Stack()##实例化栈类

其次通过栈帧实现:

def to_str(n,base):
	str1='0123456789ABCDEF'
	while n>0:
		if n<base:
			Stack.push(str1[n])
		else:
			Stack.push(str1[n%base])
			n=n//base#整数除法
	res=''
	while not Stack.isEmpty():
		res = res+str1(Stack.pop())
	return res

在python中,当一个函数被调用时,系统回分配一个栈帧去处理函数的局部变量,当执行完函数并得到一个返回值时,这个值会留在栈顶等待被调用的函数来处理。例如将整数10转换为2进制的整数在栈帧中的过程如下图所示:
python数据结构与算法-递归Recursion_第3张图片
当调用 toStr(2//2,2) 时,会在栈顶留下一个返回值“1”,这个返回值随后会被用于toStr(2//2,2)+convertString[2%2] 中替代toStr(2//2,2),使语句变为” 1”+convertString[2%2],执行后字符串‘10’就会留在栈顶,以此类推,转换为2进制的结果为‘1010’。
python数据结构与算法-递归Recursion_第4张图片

你可能感兴趣的:(数据结构)