算法设计与分析——递归算法

一 概念解释

递归(recursive)定义为一种直接或间接引用自身的定义方法,通俗的说,即是:自己调用自己的函数(或称为方法)。

二 递归算法结构

一个合法的递归包括两个部分:基础情况递归部分。基础情况以直接形式明确列举新事物的若干简单对象,递归部分给出由简单(或较简单)对象定义新的条件和方法。

三 算法思想内核

在程序设计中,处理重复性计算最常用的方法是组织迭代循环,此外还可以采用递归计算的方法,后者在非数值计算领域适用性更强。递归本质也是一种循环,将较复杂的计算或问题不断分解为较简单的子部分,最后得出结果。例如,递归算法典例:斐波那契数列的求解:
斐波那契级数的递归定义:
F(0)=0;
F(1)=1;
F(n)=F(n -1)+F(n-2) (n>1)
可写出函数:

long Fib(int n)
{
   if(n==0||n==1)
   return n;
   else
   return Fib(n-1)+Fib(n-2);
}

函数P()调用函数Q(),P称为调用函数,Q称为被调函数。当被调函数为P本身时,称其为递归函数,如Fib(n)。

四 递归算法应用

1 逆序输出正整数的各位数

——设有正整数n=123456,现要求逆序输出654321,设k位正整数为d1d2d3……dk,要输出逆序的dkdk-1……d2d1
若采用for循环的方式分离出正整数的每一位数字:

#include<stdio.h>
#include<math.h>
void getNum(int n)
{
	int s;
	int len=(int)log10(n)+1;         //获得n的位数 
	for(int i=0;i<len;i++)
	{
		s=n%10;
		printf("%d ",s);
		n=n/10;                      //更新n的取值
	}
}
int main()
{
	int n;
	scanf("%d",&n);
	getNum(n);
	return 0;
}

若采用递归方法则分为两步:首先输出末位数dk——然后输出前k-1位组成的正整数的逆序形式。

#include<iostream.h>
void Print(int n)
{
    count<<n%10;
    if(n>=10)
    Print(n/10);
}
void main()
{
    unsigned int n;
    cin>>n;
    Print(n);
}
2 汉诺塔问题

——有三个塔座:x,y,z,在塔座x上有n个直径大小各不相同的的圆盘,按直径大小从小到大编号为1,2,3……n。现要求将x塔座上的n个圆盘移到塔座y上,且仍按照相同顺序排列,即如图。圆盘移动时必须遵守下列规则:
1 每次只能移动一个圆盘;
2 圆盘可以加到塔座x,y,z中任意一个之上;
3 任何时刻都不能将一个较大的圆盘放在一个较小的圆盘之上。

在这里插入图片描述

假定圆盘从小到大编号为1~n,移动圆盘的递归算法可以粗略描述如下:
1 以塔座y为中介,将前n-1个圆盘从塔座x移到塔座z上;
2 将第n个圆盘移到塔座y上;
3 以塔座x为中介,将塔座z上的n-1个圆盘移到塔座y上。

汉诺塔问题:

#include<iostream.h>
 enum tower{A='X',B='Y',C='Z'};
 void Move(int n,tower x,tower y)
 {
	cout<<"The disk"<<n<<"is moved from"<<char(x)<<"to top of tower"  <<char(y)<<endl;
 }
 void Hanoi(int n,tower x,tower,y,tower z)
 {
	if(n){
		Hanoi(n-1,x,z,y);
		Move(n,x,y);
		Hanoi(n-1,z,y,x);
	}
 }void main()
 {
	Hanoi(4,A,B,C);
 }
单向链表转置、八皇后问题、全排列等(待完成)

五 递归树

递归树是设计好的猜测一种简单而直接的办法。顾名思义,递归树具有树的结构,其中每个节点表示一个单一子问题的代价,子问题对应某次递归函数调用,将树中每层中的代价求和,得到每层代价,然后将所有层的代价求和,便可得到所有层次的递归调用的总代价。
对于上述的斐波那契级数求解的问题(以fib(4)的构成为例):

Fib4
Fib3
Fib2
Fib0
Fib1
Fib1
Fib2
Fib0
Fib1

由图可知,在执行Fib(4)的过程中,须分别调用Fib(3)和Fib(2),而Fib(2)又分别调用Fib(1)和Fib(0)……整个过程中,Fib(0)调用了两次,Fib(1)调用了三次,Fib(2)调用了两次,并可以推想,在数据规模不断扩大的过程中,重复计算的次数也会不断提升,在此过程中浪费的时间也会愈多。

六 递归优缺点梳理

优点:程序设计简洁清晰、易于分析。
缺点:运行过程中的嵌套调用特性导致其时空效率往往相对较低。

七 递归的实现原理(待补充)

八 递归思想的应用

1 数据结构中,树、二叉树和列表常采用递归方式来定义,包括其相关操作(如二叉树树的遍历、二叉树树的元素的增删改查等)也常利用递归的方法。
2 后面即将提到的算法设计方法——分治法,也是递归思想的重要应用。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值