21
第第第第第第

递 归

Embed Size (px)

DESCRIPTION

递 归. 第二十九次课. 我们把自己内部又有 自己本身 的这种情况叫做递归 。. 一个过程 ( 或函数 ) 直接或间接调用自己本身 , 这种过程 ( 或函数 ) 叫 递归过程 ( 或函数 ). procedure b ; procedure c ; begin begin . . . . . - PowerPoint PPT Presentation

Citation preview

递 归

第二十九次课

我们把自己内部又有自己本身的这种情况叫做递归。

procedure a; begin . . . a; . . .end;这种方式是直接调用 .

procedure b; procedure c;

begin begin

. .

.

. .

c; b;

. .

. .

end; end;

这种方式是间接调用 .

一个过程 ( 或函数 ) 直接或间接调用自己本身 , 这种过程( 或函数 ) 叫递归过程 ( 或函数 ).

递 归 递 归

pascalpascal 语言中,如果在一个语言中,如果在一个函数、过程函数、过程等定等定义义内部内部又直接或间接地出现有对自身的引用,又直接或间接地出现有对自身的引用,则称它们是则称它们是递归的递归的或者是或者是递归定义递归定义的。的。

在程序中,递归是通过函数或过程的调用来在程序中,递归是通过函数或过程的调用来实现的。函数或过程直接调用其自身,称为实现的。函数或过程直接调用其自身,称为直接递归直接递归;函数或过程间接调用其自身,称;函数或过程间接调用其自身,称为为间接递归间接递归。。

如何设计递归算法

1. 确定递归公式

2. 确定边界 ( 终了 ) 条件

例例 11 阶乘函数

阶乘函数可递归地定义为:

边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果。

边界条件

递归方程

program ex1 ;var n:integer; s:longint ;

begin readln(n) ; s:=fac(n) ; writeln(n,‘!=’,s) end .

function fac(a:integer):longint ;

var t:longint;

begin

t:=1 ;

for i:=2 to a do t:=t*i;

fac:=t;

end ;

function fac(a:integer):longint ;

begin

if a=0 then fac:=1

else fac:=a*fac(a-1) ;

end ;

n!

N!N! 可以由下列公式表示:可以由下列公式表示:

输入一串以‘ !’ 结束的字符,按逆序输出。

字符串字符数组

输入: abc!

输出: !cba

program ex2 ;procedure rever ;var c:char ; begin read(c) ; if c<>’!’ then rever; write(c) ; end ;begin { 主程序 } rever ;end .

输入一串以‘ !’ 结束的字符,按逆序输出。

输入 hey!

输出 !yeh 。

procedure rever ; var c:char ; begin read(c) ; if c<>'!' then rever; write(c) ; end ;

hey!

procedure rever ; var c : char ; begin read(c) ; if c<>'!' then rever; write(c) ; end ;

procedure rever ; var c : char ; begin read(c) ; if c<>'!' then rever; write(c) ; end ;

procedure rever ; var c : char ; begin read(c) ; if c<>'!' then rever; write(c) ; end ;

c=‘e’

c=‘y’

c=‘!’

c=‘h’

程序中, c 是过程 rever 的局部变量。每一次递归调用,都要为局部变量重新分配单元,因此各层的变量 c实际上是不同的变量,它们分别用于保存执行本层调用时的输入值。

program ex2 ;procedure rever ;var c:char ; begin read(c) ; if c<>'!' then rever; write(c) ; end ;begin rever ;end .

本例如果想输出为

Hey!!yeh

如何改

program p1(input , output) ; var n : integer ; s : longint ; function fac(a : integer) : longint ; begin if a=0 then fac:=1 else fac:=a*fac(a-1) ; end ; begin readln(n) ; s:=fac(n) ; writeln(n ,‘ !=’ , s) end .

a=5 {fac(5)}

a=4 {fac(4)}

a=3 {fac(3)}

a=2 {fac(2)}

a=1 {fac(1)}

a=0 {fac(0)}

栈用于存放递归调用中不断产生的新的局部变量

a=0 {fac(0)}

a=1 {fac(1)}

a=2 {fac(2)}

a=3 {fac(3)}

a=4 {fac(4)}

a=5 {fac(5)}

11

2211

662424

120

在调用过程或函数之前,系统需完成三件事:在调用过程或函数之前,系统需完成三件事:⑴⑴ 为被调用过程的局部变量分配存储区;为被调用过程的局部变量分配存储区;⑵⑵ 将所有的实在参数、返回地址等信息传递给被调用过程保将所有的实在参数、返回地址等信息传递给被调用过程保

存;存;⑶⑶ 将控制转移到被调过程的入口。将控制转移到被调过程的入口。从被调用过程返回调用过程之前,系统也应完成三从被调用过程返回调用过程之前,系统也应完成三件工作:件工作:⑴⑴ 保存被调过程的计算结果;保存被调过程的计算结果;⑵⑵ 释放被调过程的数据区;释放被调过程的数据区;⑶⑶ 依照被调过程保存的返回地址将控制转移到调用过程。依照被调过程保存的返回地址将控制转移到调用过程。

Procedrue begin 输出 n 的最右边的一个数字; if 还有数字 then 将余下的“数字倒序” end

输入一个非负数,输出这个数的倒序数。

elseelse Procedrue reverse(n:integer); var nr,nl:integer; begin nr:=n mod 10; write(nr); nl:=n div 10; if nl<>0 then reverse(nl) end;

递归过程分析—数字倒序

用递归算法把任一给定的十进制正整数( <=32000 )转换成二进制数输出。

十进制整数与 N 进制整数之间的转换

结束 n:=0

n=n div 2 N<>0

边界条件

递归方程

用递归算法把任一给定的十进制正整数( <=32000 )转换成二进制数输出。

procedure tran(n:longint); { 递归过程 } var k:longint; begin k:=n mod 2 { 取除以 2 以后的余数 } n:=n div 2; { 取除以 2 以后的商 } if n<>0 then tran(n); { 直到商为 0 ,结束递归过程 } write(k) end;