数据结构-堆栈

时间:2025-03-14 08:46:13

递归算法

递归(Recursion)是一种很特殊的算法,其定义是:加入一个函数或子程序是由自身所定义或调用的,就称为递归。递归至少需要两个条件:

  • 可以反复执行的递归过程
  • 一个跳出执行过程的出口

比如数学上的阶乘函数,可以看做是典型的递归范例,一般以!来代表阶乘。例如4的阶乘就是4!

4!= 4 x 3 x 2 x 1

4! = (4 * 3!)---->(4 * 3 * 2!) ------>(4 * 3 * 2 * 1)

函数算法表示是

def factorial(i):		if i == 0:				return 1		else:				ans = i * factorial(i - 1)		#反复执行递归过程

使用for循环设计一个计算0!~ n!的递归程序

sum = 1n = int(input('请输入n=''))for i in range (0,n+1):		for j in range(i ,0,-1):				sum *= j				print('%d != %3d' % (i,sum))		sum = 1

递归算法又可以分为直接递归和间接递归:

  • 直接递归(Direct Recursion):在递归函数中允许直接调用该函数自身

    def Fun(...):		.......if ....:		Fun(...)		......
    
  • 简介递归(Indirect Recursion):在递归函数中调用其他递归函数,再从其他递归函数调用回原来的递归函数

    def Fun1(...):	......if ......:		Fun2(...)		.......		def Fun2(...):		......if ......:		Fun1(...)		......
    

斐波拉契数列

0 n=0
Fn 1 n=1
Fn-1 + Fn-2 n=2,3,4,5,…(n为正整数)

简单来说,这就是一个数列的第零项是0,第一项是1,这个数列其他后续项的值是前两项的数值之和。

def fib(n):				if n == 0:				return 0		elif n == 1 or n == 2:				return 1		else:			#否则返回fib(n-1) + fib(n-2)				return (fib(n-1) + fib(n-2))		

例子:设计一个计算第n项斐波拉契数列的递归程序:

def fib(n):		if n == 0:				return 0		elif n == 1 or n == 2:				return 1		else:				return (fib(n - 1) + fib(n - 2))				n = int ( input ("请输入n="))for i in range(n + 1):		print('fib(%d) = %d' % (i,fib(i)))

汉诺塔问题

汉诺塔问题也是很典型的递归方式和堆栈来解决,因为它满足递归的两大特性:①有反复执行的过程②有停止的出口

汉诺塔的游戏规则就是把一定数量的盘子每次移动一个,全部从第一个桩移动到第三个桩上,在移动的过程中要保证大盘子在下面

借助递归的思想,加入有n个盘子,我们可以将n个盘子看做两个组成结构,就是n-1个盘子和一个盘子,每次都是将n-1个盘子移动到第二个桩上,将一个盘子(最大的)移动到第三个桩上,然后将第二个桩变换为第一个桩,继续将剩下的n-1个盘子分为两个结构进行移动,直到不能分为止

移动步骤:

  • 将n-1个盘子从木桩1移动到木桩2
  • 将第n个最大的盘子从木桩1移动到木桩3
  • 将n-1个盘子从木桩2移动到木桩3
    • 就是把木桩2当做是木桩1逐次分解进行迭代

算法实现:

"""
n:需要移动的盘子数量
p1,p2,p3:三根木桩
"""
def hanoi(n,p1,p2,p3):
    if n == 1:
        print("盘子从%d移动到了%d"%(p1,p3))
    else:
        hanoi(n-1,p1,p3,p2)
        print("盘子从%d移动到%d"%(p1,p3))
        hanoi(n-1,p2,p1,p3)

j = int(input("请输入要移动盘子的数量:"))
hanoi(j,1,2,3)