数据结构JAVA版
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第六章 递归
1
何谓递归
2 函数调用与参数传递
3
数学问题
4
汉诺塔问题
5
N皇后问题
6
迷宫问题
6.1 递归定义
❖ 递归简单说就是子程序或函数重复地调用自己,并 传入不同的变量来执行的一种程序设计技巧,而递 归在程序设计及解题上也是一种有力且重要的工具, 帮助程序设计者解决复杂的问题,并精简程序结构。
❖ 下面的程序实例来说明乘法运算中递归的应用
public static void main (String args[ ])
返回地址2
返回地址1
6.2 函数调用与参数传递
❖ 当ProcedureB执行完后,”返回地址 2,便从堆栈中被取出 (POP),继续执 行ProcedureA中未执行的程序语句。 这时堆栈中的内容为:
返回地址1
6.2 函数调用与参数传递
❖ 当ProcedureA执行完后,”返回地址1”便 从堆栈中被取出 (POP),继续执行主程 序中未执行的程序语句。这时堆栈中 无任何内容。
说明: 处理递归问题,常采用if 语句来判断是否符合递归结束条件, 其算法格式如下: if (符合递归结束条件) then 返回答案 else 使用递归将程序分割为更简单的小程序
6.2 函数调用与参数传递
❖ 在程序语言中,采用堆栈来记录函数调用后的返回 地址。例如有程序如下(以下的说明,以一般程序语 言为例,而非面向对象程序语言中的方法):
❖ 对于递归而言,也是反复调用子程序 的结构,如同上列函数的调用,递归 也需要运用堆栈来记录程序的返回地 址。
❖ 利用一个程序实例来说明递归程序执 行的流程
程序目的
6.2 函数调用与参数传递
程序构思
❖ 递归结束条件:当字符串中每个字符都输出时
❖ 递归执行部分:从字符串到后一个字符开始输出,依 次输出直到字符串最前的字符。
public static int Multiply(int M, int N) {
int Result;
if (N= =1) Result = M; //递归结束条件
else Result = M + Multiply(M, N-1); //递归执行部分
return Reasult; } }
6.1 递归定义
❖ 需先知道字符串的内容及长度。
程序源代码
import ConsoleReader . *; 数据输入类
// 引入已定义的
ቤተ መጻሕፍቲ ባይዱ
public class reverse
{ public static String StringA = new String( ); // 声 明字符串变量 public static int LengthA; // 字符串长度变量
返回地址1
6.2 函数调用与参数传递
❖ 调用ProcedureA后,当ProcedureA 执 行到”ProcedureB()”(调用子程序B)这 行时,堆栈仍需记录下一行程序语句的 地址,也就是将”返回地址2”存入 (PUSH)堆栈中,以便在ProcedureB执 行完之后,能顺利返回ProcedureA中继 续执行未执行的程序语句.这时堆栈中 的内容为:
程序构思 假设欲计算出13*4,则: 13*4=13+(13*3) =13+(13+(13*2)) =13+(13+(13+(13*1))) =13+(13+(13+13)) =13+(13+26) =13+39 =52
6.1 递归定义
程序源代码
import ConsoleReader .*;
程序说明 归纳解递归问题的几个步骤:
步骤1:了解题意是否为适合用递归来解题 步骤2: 决定递归结束条件 (Stopping Cases) 步骤3::决定递归执行部分 (Recursive Step) 由题意可知,每次执行的过程相似,惟一不同的是
为其中的一个传入参数,每次执行皆递减.递归 结束的条件为当被乘数为1时,则返回乘数的 值.否则继续调用程序并递减地传入被乘数值.
6.1 递归定义
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归乘法运算 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - -
// 引入已定义的数据输入类
public class multiply
{
public static void main (String args[])
{
int NumA;
//乘数变量
int NumB;
//被乘数变量
int Product; //乘积变量
System.out.print(“Please enter Number A : “); //输入乘数 ConsoleReader console = new ConsoleReader (System.in); NumA =console.readInt(); System.out.print(“Please enter Number B : “); //输入被乘数 NumB =console.readInt(); Product = Multiply(NumA, NumB); System.out.println(NumA+” *”+NumB+” = “+Product); }
int ProcedureA ( ) /* 子程序A */
{
……
ProcedureB ( ); /* 调用子程序B */
……
/* 返回地址2 */
} int ProcedureB ( ) /* 子程序B */
{
……
} void mian ( )
/* 主程序
*/
{
……
ProcedureA ( ); /* 调用子程序A */
……
/* 返回地址1 */
}
6.2 函数调用与参数传递
❖ 则当主程序执行到”ProcedureA()”(调 用子程序A)这行时,堆栈需记录下一 行程序语言的地址,也就是将”返回 地址1”存入(PUSH)堆栈中,以便在 ProcedureA 执行完之后,能顺利返回 主程序中继续执行未执行的程序语句。 这时堆栈中的内容为:
1
何谓递归
2 函数调用与参数传递
3
数学问题
4
汉诺塔问题
5
N皇后问题
6
迷宫问题
6.1 递归定义
❖ 递归简单说就是子程序或函数重复地调用自己,并 传入不同的变量来执行的一种程序设计技巧,而递 归在程序设计及解题上也是一种有力且重要的工具, 帮助程序设计者解决复杂的问题,并精简程序结构。
❖ 下面的程序实例来说明乘法运算中递归的应用
public static void main (String args[ ])
返回地址2
返回地址1
6.2 函数调用与参数传递
❖ 当ProcedureB执行完后,”返回地址 2,便从堆栈中被取出 (POP),继续执 行ProcedureA中未执行的程序语句。 这时堆栈中的内容为:
返回地址1
6.2 函数调用与参数传递
❖ 当ProcedureA执行完后,”返回地址1”便 从堆栈中被取出 (POP),继续执行主程 序中未执行的程序语句。这时堆栈中 无任何内容。
说明: 处理递归问题,常采用if 语句来判断是否符合递归结束条件, 其算法格式如下: if (符合递归结束条件) then 返回答案 else 使用递归将程序分割为更简单的小程序
6.2 函数调用与参数传递
❖ 在程序语言中,采用堆栈来记录函数调用后的返回 地址。例如有程序如下(以下的说明,以一般程序语 言为例,而非面向对象程序语言中的方法):
❖ 对于递归而言,也是反复调用子程序 的结构,如同上列函数的调用,递归 也需要运用堆栈来记录程序的返回地 址。
❖ 利用一个程序实例来说明递归程序执 行的流程
程序目的
6.2 函数调用与参数传递
程序构思
❖ 递归结束条件:当字符串中每个字符都输出时
❖ 递归执行部分:从字符串到后一个字符开始输出,依 次输出直到字符串最前的字符。
public static int Multiply(int M, int N) {
int Result;
if (N= =1) Result = M; //递归结束条件
else Result = M + Multiply(M, N-1); //递归执行部分
return Reasult; } }
6.1 递归定义
❖ 需先知道字符串的内容及长度。
程序源代码
import ConsoleReader . *; 数据输入类
// 引入已定义的
ቤተ መጻሕፍቲ ባይዱ
public class reverse
{ public static String StringA = new String( ); // 声 明字符串变量 public static int LengthA; // 字符串长度变量
返回地址1
6.2 函数调用与参数传递
❖ 调用ProcedureA后,当ProcedureA 执 行到”ProcedureB()”(调用子程序B)这 行时,堆栈仍需记录下一行程序语句的 地址,也就是将”返回地址2”存入 (PUSH)堆栈中,以便在ProcedureB执 行完之后,能顺利返回ProcedureA中继 续执行未执行的程序语句.这时堆栈中 的内容为:
程序构思 假设欲计算出13*4,则: 13*4=13+(13*3) =13+(13+(13*2)) =13+(13+(13+(13*1))) =13+(13+(13+13)) =13+(13+26) =13+39 =52
6.1 递归定义
程序源代码
import ConsoleReader .*;
程序说明 归纳解递归问题的几个步骤:
步骤1:了解题意是否为适合用递归来解题 步骤2: 决定递归结束条件 (Stopping Cases) 步骤3::决定递归执行部分 (Recursive Step) 由题意可知,每次执行的过程相似,惟一不同的是
为其中的一个传入参数,每次执行皆递减.递归 结束的条件为当被乘数为1时,则返回乘数的 值.否则继续调用程序并递减地传入被乘数值.
6.1 递归定义
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归乘法运算 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - -
// 引入已定义的数据输入类
public class multiply
{
public static void main (String args[])
{
int NumA;
//乘数变量
int NumB;
//被乘数变量
int Product; //乘积变量
System.out.print(“Please enter Number A : “); //输入乘数 ConsoleReader console = new ConsoleReader (System.in); NumA =console.readInt(); System.out.print(“Please enter Number B : “); //输入被乘数 NumB =console.readInt(); Product = Multiply(NumA, NumB); System.out.println(NumA+” *”+NumB+” = “+Product); }
int ProcedureA ( ) /* 子程序A */
{
……
ProcedureB ( ); /* 调用子程序B */
……
/* 返回地址2 */
} int ProcedureB ( ) /* 子程序B */
{
……
} void mian ( )
/* 主程序
*/
{
……
ProcedureA ( ); /* 调用子程序A */
……
/* 返回地址1 */
}
6.2 函数调用与参数传递
❖ 则当主程序执行到”ProcedureA()”(调 用子程序A)这行时,堆栈需记录下一 行程序语言的地址,也就是将”返回 地址1”存入(PUSH)堆栈中,以便在 ProcedureA 执行完之后,能顺利返回 主程序中继续执行未执行的程序语句。 这时堆栈中的内容为: