数据结构 (JAVA 版 )

50
The course of elaboration for Data Structures 数数数数 (JAVA 数 ) www.YTVC.com.cn 烟烟烟烟烟烟烟烟烟

description

烟台职业学院精品课. 数据结构 (JAVA 版 ). www.YTVC.com.cn. 1. 2. 3. 4. 5. 何谓递归. 函数调用与参数传递. 数学问题. 汉诺塔问题. N 皇后问题. 第六章 递归. 6. 迷宫问题. 6.1 递归定义. 递归简单说就是子程序或函数重复地调用自己,并传入不同的变量来执行的一种程序设计技巧,而递归在程序设计及解题上也是一种有力且重要的工具,帮助程序设计者解决复杂的问题 , 并精简程序结构。 下面的程序实例来说明乘法运算中递归的应用 程序构思 假设欲计算出 13*4 ,则: 13*4=13+(13*3) - PowerPoint PPT Presentation

Transcript of 数据结构 (JAVA 版 )

Page 1: 数据结构 (JAVA 版 )

The

cour

se o

f ela

bora

tion

for D

ata

Stru

ctur

es

数据结构 (JAVA 版 )www.YTVC.com.cn

烟台职业学院精品课

Page 2: 数据结构 (JAVA 版 )

第六章 递归 何谓递归 1

函数调用与参数传递 2

数学问题 3

汉诺塔问题 4

N皇后问题 5

6 迷宫问题

Page 3: 数据结构 (JAVA 版 )

6.1 递归定义 递归简单说就是子程序或函数重复地调用自己,并传入不同的变量来执行的一种程序设计技巧,而递归在程序设计及解题上也是一种有力且重要的工具,帮助程序设计者解决复杂的问题 , 并精简程序结构。 下面的程序实例来说明乘法运算中递归的应用

程序构思假设欲计算出 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

Page 4: 数据结构 (JAVA 版 )

6.1 递归定义 程序源代码

import ConsoleReader .*; // 引入已定义的数据输入类 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); }

Page 5: 数据结构 (JAVA 版 )

6.1 递归定义 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归乘法运算// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - public static int Multiply(int M, int N) { int Result; if (N= =1) Result = M; // 递归结束条件 else Result = M + Multiply(M, N-1); // 递归执行部分 return Reasult; }}

Page 6: 数据结构 (JAVA 版 )

6.1 递归定义 程序说明 归纳解递归问题的几个步骤: 步骤 1 :了解题意是否为适合用递归来解题 步骤 2 : 决定递归结束条件 (Stopping Cases)

步骤 3: :决定递归执行部分 (Recursive Step)由题意可知 , 每次执行的过程相似 , 惟一不同的是为其中的一个传入参数 , 每次执行皆递减 . 递归结束的条件为当被乘数为 1 时 , 则返回乘数的值 . 否则继续调用程序并递减地传入被乘数值 . 说明 :

处理递归问题,常采用 if 语句来判断是否符合递归结束条件,其算法格式如下: if ( 符合递归结束条件 ) then 返回答案 else 使用递归将程序分割为更简单的小程序

Page 7: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 在程序语言中,采用堆栈来记录函数调用后的返回地址。例如有程序如下 ( 以下的说明,以一般程序语言为例,而非面向对象程序语言中的方法 ) :

int ProcedureA ( ) /* 子程序 A */ { …… ProcedureB ( ); /* 调用子程序 B */ …… /* 返回地址 2 */ } int ProcedureB ( ) /* 子程序 B */ { …… } void mian ( ) /* 主程序 */ { …… ProcedureA ( ); /* 调用子程序 A */ …… /* 返回地址 1 */ }

Page 8: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 则当主程序执行到” ProcedureA()”( 调用子程序 A) 这行时,堆栈需记录下一行程序语言的地址,也就是将”返回地址 1” 存

入 (PUSH) 堆栈中,以便在ProcedureA 执行完之后,能顺利返回主程序中继续执行未执行的程序语句。这时堆栈中的内容为 :

返回地址 1

Page 9: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 调用 ProcedureA 后 , 当 ProcedureA 执行到” ProcedureB()”( 调用子程序

B) 这行时 , 堆栈仍需记录下一行程序语句的地址 , 也就是将”返回地址 2” 存入(PUSH) 堆栈中 , 以便在 ProcedureB 执行完之后 , 能顺利返回 ProcedureA 中继续执行未执行的程序语句 . 这时堆栈中的内容为:

返回地址 1

返回地址 2

Page 10: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 当 ProcedureB 执行完后,”返回地址2 ,便从堆栈中被取出 (POP) ,继续执行

ProcedureA 中未执行的程序语句。这时堆栈中的内容为:

返回地址 1

Page 11: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 当 ProcedureA 执行完后 ,” 返回地址 1”便从堆栈中被取出 (POP), 继续执行主程序中未执行的程序语句。这时堆栈中无任何内容。 对于递归而言,也是反复调用子程序的结构,如同上列函数的调用,递归也需要运用堆栈来记录程序的返回地址。 利用一个程序实例来说明递归程序执行的流程

程序目的• 运用递归设计一个将字符串反转的程序

Page 12: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 程序构思

• 递归结束条件:当字符串中每个字符都输出时• 递归执行部分:从字符串到后一个字符开始输出,依次输出直到字符串最前的字符。• 需先知道字符串的内容及长度。

程序源代码import ConsoleReader . *; // 引入已定义的数据输入类 public class reverse{ public static String StringA = new String( ); // 声明字符串变量 public static int LengthA; // 字符串长度变量 public static void main (String args[ ])

Page 13: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递 { System.out.print(“Please enter string : “); // 输入原字符串 ConsoleReader console = new ConsoleReader

(System . in); StringA = console . readLine ( ); LengthA = StringA . length( ); // 取得字符串长度 System.out.print(“The reverse string : “); Reverse (0); // 调用递归函数 System.out.println(“ “); }

Page 14: 数据结构 (JAVA 版 )

6.2 函数调用与参数传递// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归字符串反转 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void Reverse(int N) {

if (N < LengthA) { Reverse (N+1); // 递归执行部分 System.out.print(StringA . charAt (N); } }}

Page 15: 数据结构 (JAVA 版 )

6.3 数学问题 阶乘问题

阶乘定义• 数学上阶乘 (Factorial) 的运算,其定义为:• 1 n<=1• n!=

n*(n-1)! n>1

从上述的式子,我们可运用递归来设计阶乘的运算。 当 n 小于或等于 1 ,返回阶乘为 1 ,我们定义出 0!=1 、 1!=1 当 n 大于 1 时,返回阶乘为 n! = n*(n-

1)!

Page 16: 数据结构 (JAVA 版 )

6.3 数学问题 程序实现

import ConsoleReader . *; // 引入已定义的数据输入类 public class factor{ public static void main (String args[ ]) { int Number; // 运算数值变量 int Factorial; // 阶乘数值变量 System.out.print(“Please enter a number :

“); ConsoleReader console = new

ConsoleReader (System . in);

Page 17: 数据结构 (JAVA 版 )

6.3 数学问题 Number = console .readInt ( ) ; // 输入数值 Factorial = Factor(Number); // 调用递归函数 System.out.print(Number+”!”); System.out.println(“ = “+Factorial); // 输出运算结果 }// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归阶乘运算// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static int Factor(int N) { if (N <= 1) // 递归结束条件 return 1; else return N * Factor(N-1); // 递归执行部分 }}

Page 18: 数据结构 (JAVA 版 )

6.3 数学问题 最大公因子问题

问题定义 • 数学上求最大公因子 (Great Common Divisor) 的运算,通常使用辗转相除法,反复计算到余数为零为止。这种方法也成为欧几里得定理 (Euclid’s

Algorithm) ,其定义为: M N=0GCD(M,N)= GCD(N,M%N) N=0

• 上述的式子,可用递归来设计。 当 N 等于 0 ,返回最大公因子为 M 。当 N 大于 0 时,返回最大公因子为 GCD(N,M%N) 。

Page 19: 数据结构 (JAVA 版 )

6.3 数学问题 程序实现

import ConsoleReader . *; // 引入已定义的数据输入类 public class gcd{ public static viod main (String args[ ]) { int NumberA; // 运算数值变量 int NumberB; // 运算数值变量 int Result; // 运算结果变量 System.out.println(“The Great Common Divisor of

NumberA, NumberB”); System.out.print(“Please enter number A : “); // 输入数值 A ConsoleReader console = new ConsoleReader

(System . in);

Page 20: 数据结构 (JAVA 版 )

6.3 数学问题 NumberA = console .readInt ( ); System.out.print(“Please enter number B :

“); // 输入数值 B NumberB = console .readInt ( ); Result = GCD(NumberA, NumberB); // 调用递归函数System.out.print(“GCD(“+NumberA+”,”+Number

B+”)”);System.out println(“ = “+Result );}

Page 21: 数据结构 (JAVA 版 )

6.3 数学问题// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归求最大公因子// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static int GCD(int M, int N) { if (N = = 0) // 递归结束条件 return M; else return GCD(N , M%N); // 递归执行部分 }}

Page 22: 数据结构 (JAVA 版 )

6.3 数学问题 费氏级数问题

问题定义 • 数学上有一种费氏级数 (Fibonacci Numbers), 其定义为: N N<=1Fib(N)= Fib(N-1)+Fib(N-2) N>1

• 上述的式子,可用递归来设计。 –当 N 小于或等于 1 ,返回费氏级数数值为 N 。–当 N 大于 1 时,返回费氏级数值为 Fib(N-1) + Fib(N-2) 。

Page 23: 数据结构 (JAVA 版 )

6.3 数学问题 程序实现

• 程序源代码import ConsoleReader . * ; // 引入已定义的数据输入类 public class fib{ public static void main (String args [ ]) { int NumberA; // 运算数值变量 int Result; // 运算结果变量 System.out.println(“The Fibonacci Numbers”);

System.out.print(“Please enter a number : “); // 输入数值 ConsoleReader console = new ConsoleReader (System . in); NumberA = console . readerInt( ); Result = Fib(NumberA); // 调用递归函数 System.out.print(“Fibonacci Numbers of “+NumberA); System.out.println(“ = “+Result); }

Page 24: 数据结构 (JAVA 版 )

6.3 数学问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// 递归求费氏级数// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static int Fib(int N) { if (N< = 1) // 递归结束条件 return N; else return Fib(N-1) + Fib(N-2); // 递归执行部分 }}

Page 25: 数据结构 (JAVA 版 )

6.3 数学问题 组合公式

问题定义 • 数学上组合公式的求法,其定义为:

n-1

上述的式子可运用递归来设计当 n 等于 m 或 m=0 时,返回 1

否则返回 Cm + Cm-1 n-1

Page 26: 数据结构 (JAVA 版 )

6.3 数学问题 程序实现

• 程序源代码import ConsoleReader . *; // 引入已定义的数据输入类 public class comb{ public static void main (String args[ ] ) { int NumberN; // 运算数值变量 int NumberM; // 运算数值变量 int Result; // 运算结果变量System.out.println(“The Combination Number of two

Numbers .”) System.out.print(“Please enter number N : ”); // 输入数值 N ConsoleReader console = new ConsoleReader

(System . in);

Page 27: 数据结构 (JAVA 版 )

6.3 数学问题 NumberN = console.readInt( ); System.out .print(“Please enter Number M : ”); // 输入数值 M NumberM = console.readInt( ); if (Numbern >=NumberM) { Result = Comb(NumberN, NumberM); // 调用递归函数

System.out.print(“Comb(“+NumberN+”,”+NumberM+”)”);

System.out.println(“ = “+Result); } else System.out.println(“Error: N < M !!”); }

Page 28: 数据结构 (JAVA 版 )

6.3 数学问题//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// 递归求组合公式//- - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - public static int Comb(int N, int M) { if ((N = = M) | | (M = =0) ) // 递归结束条件 return 1; else // 递归执行部分 return Comb(N-1,M) + Comb(N-1,M-1); }}

Page 29: 数据结构 (JAVA 版 )

6.4 汉诺塔问题 问题的提出

相传在某一座古庙有 3 根木桩,有 24 个铁盘由小到大地放置在其中一根木桩上,庙中流传着一个传说:“如果有一天能把 24 个铁盘,从其中一个木桩移至另一根木桩,且必须遵守着以下两个原则: (1) 每一天只能搬动一个铁盘,而且只能从最上面的铁盘开始搬动。 (2) 必须维持较小的铁盘在上方的原则,则当 24 个铁盘完全搬至另一个木桩时,世界就会永久和平”这个问题就是著名的汉诺塔 (Tower of Hanoi ) 问题。 程序实现

程序目的 • 运用递归来解汉诺塔问题

Page 30: 数据结构 (JAVA 版 )

6.4 汉诺塔问题 程序构思

• 由上述对 n 个铁盘的汉诺塔问题分析中,我们定义铁盘原先所在的桩为”来源桩” (Source) ,铁盘欲移往的桩为”目的桩” (Destination) ,而另一个桩为”辅助桩” (Auxliiary) 。• 当未移往目的桩的铁盘数为 1 时,则将最后所剩的铁盘移至目的桩即完成工作。• 否则:

– 将前 N-1 个铁盘从来源桩移往辅助桩– 将编号为 N 的铁盘从来源桩移往目的桩– 将前 N-1 个铁盘从辅助桩移往目的桩

• 递归结束条件: 当未移往目的桩的铁盘数为 1 时,将编号为 1 的铁盘移至目的桩。• 递归执行部分:

– a. 将前 N-1 个铁盘从来源桩移往辅助桩– b 将编号为 N 的铁盘从来源桩移往目的桩– c. 将前 N-1 个铁盘从辅助桩移往目的桩

Page 31: 数据结构 (JAVA 版 )

6.4 汉诺塔问题 程序源代码

import ConsoleReader .*; // 引入已定义的数据输入类 public class Hanoi { public static int Counter; // 计数器变量 public static void main(String args[ ]) { int NumberDisk; // 铁盘数目变量 String Source = new String( ); // 来源桩变量 String Destination = new String( ); // 目的桩变量

String Auxiliary = new String( ); // 辅助桩变量 Counter = 0; System.out.println(“The Tower of Hanoi program.”); System.out.print(“Please enter the number of disks : “);

Page 32: 数据结构 (JAVA 版 )

6.4 汉诺塔问题 // 输入铁盘数

ConsoleReader console = new ConsoleReader(System.in); NumberDisk = console.readInt( ); System.out.print(“The Source peg : “); Source = console.readLine( ); // 输入来源桩 System.out.print(“The Auxiliary : “); Auxiliary = console.readLine( ); // 输入辅助桩

System.out.print(“The Destination : “); Destination = console.readLine ( ); // 输入目的桩 // 调用递归函数 Hanoi(Source, Destiation, Auxiliary, NumberDisk); }

Page 33: 数据结构 (JAVA 版 )

6.4 汉诺塔问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归解汉诺塔问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static void Hanoi(String From,String To,String Auxiliary, int N) { if (N = =1) // 递归结束条件 { Counter++; // 计数器递增 System.out.print(“Step “+counter+” : “); System.out.print(“Move disk 1 from peg-“+From); System.out.println(“ to peg-“+To); } else // 递归执行部分 { // 将目的桩和辅助桩交换 Hanoi(From,Auxiliary,to,N-1); Counter++; // 计数器递增 System.out.print(“Step “+Counter+” : “); System.out.print(“Move disk 1 from peg-“+From); System.out.println( “ to peg-“+To); // 将来源桩和辅助桩交换 Hanoi(Auxiliary, To, From, N-1); } } }

Page 34: 数据结构 (JAVA 版 )

6.5 N 皇后问题 问题的提出

在国际象棋中,皇后的势力范围包括上、下、左、右、左上、左下、右上、右下八个方向。 N 皇后问题就是求在一个 N*N 的棋盘中放置 N 个皇后的解法。 程序实现

程序目的 • 运用递归来解 N 皇后问题

程序构思 • 必须先判断传入的坐标位置是否可放置皇后,判断该坐标上、下、左、右、左上、左下、右上、右下八个方向是否有其他的皇后,有返回 false ,无返回 ture ) 。

Page 35: 数据结构 (JAVA 版 )

6.5 N 皇后问题 • 假设传入的坐标为 (LocX,LocY) ,棋盘大小为 N*N 。• 坐标上方 : (LocX,LocY-1) 到 (LocX,0) 是否有其他的皇后。• 坐标下方 : (LocX,LocY+1) 到 (LocX,N-1) 是否有其他的皇后。• 坐标左方 : (LocX-1,LocY) 到 (0,LocY) 是否有其他的皇后。• 坐标右方 : (LocX+1,LocY) 到 (N-1,LocY) 是否有其他的皇后。• 坐标左上方 : (LocX-1,LocY-1) 到 (LocX,0) 或 (0,LocY) 是否有其他的皇后。• 坐标右上方 : (LocX+1,LocY-1) 到 (LocX,0) 或 (N-1,LocY) 是否有其他的皇后。• 坐标左下方 : (LocX-1,LocY+1) 到 (LocX,N-1) 或 (0,LocY) 是否有其他的皇后。• 坐标右下方 : (LocX+1,LocY+1) 到 (LocX,N-1) 或 (N-1,LocY)是否右其他的皇后。• 递归结束条件 : 当 N 个皇后皆放置成功• 递归执行部分 : 判断传入坐标是否可放置皇后 , 可以放置则依序递归放置下一个皇后。

Page 36: 数据结构 (JAVA 版 )

6.5 N 皇后问题 程序源代码 import ConsoleReader . *; // 引入已定义的数据输入类 public class queen { // 声明 8*8 的空白棋盘 public static char Chessboard [ ] [ ] = new char [8] [8]; public static void main (String args[ ]) { int i , j; // 循环计数变量 for (i=0; i<8; i++) for (j=0; j<8; j++) Chessboard [i] [j]=’x’; N_Queens(0,0,0); System.out.println(“The graph of 8 Queens on the

Chessboard .”); System.out..println(“ 0 1 2 3 4 5 6 7 “); System.out.println(“ +---+---+---+---+---+---+---+---+”);

Page 37: 数据结构 (JAVA 版 )

6.5 N 皇后问题

for(i=0; i<8; i++) { System.out.print(“ “+i+” |”); for(j=0 j<8; j++) System.out.print(“-“+Chessboard[i] [j]

+”-|”); System.out.println(“”); System.out.println(“ +---+---+---+---+---+---+---

+---+”); } {

Page 38: 数据结构 (JAVA 版 )

6.5 N 皇后问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 递归解 N 皇后问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- public static int N_Queens(int LocX, int LocY, int

Queens) { int i , j; // 循环计数变量 int Result = 0; if( Queens = =8 ) // 递归结束条件 return 1; else if( QueenPlace (LocX,LocY) ) { Chessboard [LocX] [LocY] = ‘Q’;

Page 39: 数据结构 (JAVA 版 )

6.5 N 皇后问题 for(i=0; i<8; i++) for(j=0; j<8; j++) { Result +=N_Queens(i , j, Queens+1); if (Result >0 ) break; } if ( Result >0) return 1; else { Chessboard [LocX][LocY] = ‘x’; return 0; } } else return o; }

Page 40: 数据结构 (JAVA 版 )

6.5 N 皇后问题 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 判断传入坐标是否可放置皇后 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static Boolean QueenPlace (int LocX,int LocY) { int i , j; if(Chessboard[LocX] [LocY] !=’x’); // 判断是否有皇后 return false; for(j=LocY-1;j>=0;j--) // 判断上方是否有皇后 if (Chessboard[LocX] [j] !=’x’) return false; for(j=LocY+1;j<8;j++) // 判断下方是否有皇后 if(Chessboard[LocX] [j] !=’x’) return false;

Page 41: 数据结构 (JAVA 版 )

6.5 N 皇后问题 for(i=LocX-1;i>=0;i--) // 判断左方是否有皇后 if (Chessboard[i] [LocY] !=’x’) return false; for(i=LocX+1;i<8;i++) // 判断右方是否有皇后 if (Chessboard[i] [LocY] !=’x’) return false; i = LocX -1; j = LocY-1; while (i<=0&& j>=0) // 判断左上方是否有皇后 if (Chessboard[i--] [j--] !=’x’) return false; i = LocX+1; j = LocY-1; while (i<8 && j>=0) // 判断右上方是否有皇后 if (Chessboard[i++] [j--] !=’x’) return false;

Page 42: 数据结构 (JAVA 版 )

6.5 N 皇后问题 i = LocX-1; j = LocY+1; while (i>=0 && j<8) // 判断左下方是否有皇后 if (Chessboard[i--] [j++] !=’x’) return false; i = LocX+1; j = LocY+1; while (i<8 && j<8) // 判断右下方是否有皇后 if (Chessboard[i++] [j++] !=’x’) return false; return true; } }

Page 43: 数据结构 (JAVA 版 )

6.5 N 皇后问题 程序运行结果C: \ DS\ JAVA\ CH06>javac queen .javaC: \ DS\ JAVA\ CH06>java queenThe graph of 8 Queens on the Chessboard. 0 1 2 3 4 5 6 7 +- - -+- - -+- - -+- - - +- - -+- - -+- - -+- - -+| -Q- | -X- | -X-| -X- | -X- | -X- | -X- | -X- || -X- | -X- | -X-| -X- | -Q- | -X- | -X- | -X- || -X- | -X- | -X-| -X- | -X- | -X- | -X- | -Q- || -X- | -X- | -X-| -X- | -X- | -Q- | -X- | -X- || -X- | -X- | -Q-| -X- | -X- | -X- | -X- | -X- || -X- | -X- | -X-| -X- | -X- | -X- | -Q- | -X- || -X- | -Q- | -X-| -X- | -X- | -X- | -X- | -X- || -X- | -X- | -X-| -Q- | -X- | -X- | -X- | -X- | +- - -+- - -+- - -+- - - +- - -+- - -+- - -+- - -+C: \ DS\ JAVA\ CH06>

Page 44: 数据结构 (JAVA 版 )

6.6 迷宫问题 问题的提出

迷宫问题是指在一个 m*n 的矩阵当中,其中” 0” 代表可以行走的区域,” 1” 代表不可行走的区域,当你处在迷宫的任何一个位置,除了不可行走的区域外,其余皆可以往上、下、左、右、左上、左下、右上、右下八个方向行走来找寻迷宫出口。 程序实现

程序目的 • 运用递归来解迷宫问题

程序构思 • 递归结束条件:当已经走到出口时 ( 当出口 (6,5), 标记

为 2 时 )• 递归执行部分: 判断传入坐标是否可走• 如果可以走的话,则递归调用往上 , 往右上 , 往右 , 往右下 , 往下 , 往左下 , 往左 , 往左上坐标是否可走。可走的话,返回 1 。不可走的话,标记改为 3( 已走过 ,但为能有通路 ) 。

Page 45: 数据结构 (JAVA 版 )

6.6 迷宫问题 程序源代码

import ConsoleReader . *; // 引入已定义的数据输入类 public class maze{ public static int Maze[ ] [ ] = { // 声明 5*4 的迷

宫 ,外围不可走 {1 ,1 ,1 ,1 ,1 ,1 ,1 }, {1 ,0 ,1 ,0 ,0 ,0 ,1 }, {1 ,1 ,0 ,1 ,1 ,0 ,1 }, {1 ,1 ,0 ,1 ,1 ,0 ,1 }, {1 ,1 ,1 ,0 ,1 ,1 ,1 }, {1 ,0 ,0 ,1 ,0 ,1 ,1 }, {1 ,1 ,1 ,1 ,0 ,0 ,1 }, {1 ,1 ,1 ,1 ,1 ,1 ,1 } };

Page 46: 数据结构 (JAVA 版 )

6.6 迷宫问题 public static void main (String args[ ]) { int i , j ; // 循环计数变量 System.out.println(“= =Problem of Maze = =”); System.out.println(“The Maze source is (1,1).”); System.out.println(“The Maze Destination is (6,5) .”); Way(1,1); System.out.println(“The graph of Maze.”); System.out.println(“ 0 1 2 3 4 5 6 “); System.out.println(“ +---+---+---+---+---+---+---+”); for(i=0;i<8;i++) {

Page 47: 数据结构 (JAVA 版 )

6.6 迷宫问题 System.out.print(“ “+i+” | “); for(j=0;j<7;j++) System.out.print(“-“+Maze[i] [j]+”-|”); System.out.println(“ ”); System.out.println(“ +---+---+---+---+---+---+---+”); } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// 递归解迷宫问题// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static boolean Way(int LocX,int LocY) { if (Maze[6] [5] = =2) // 递归结束条件 return true; else // 递归执行部分

Page 48: 数据结构 (JAVA 版 )

6.6 迷宫问题 if (Maze[LocX] [LocY] = =0) { Maze[LocY] [LocX] = 2; if (Way(LocX,LocY-1) ) return true; else if (Way(LocX+1,LocY-1) ) return true; else if (Way(LocX+1,LocY) ) return true; else if (Way(LocX+1,LocY+1) ) return true; else if (Way(LocX,LocY+1) ) return true; else if (Way(LocX-1,LocY+1) ) return true;

Page 49: 数据结构 (JAVA 版 )

6.6 迷宫问题 else if (Way(LocX-1,LocY) ) return true; else if (Way(LocX-1,LocY-1) ) return true; else { Maze[LocY] [LocX] = 3; return false; } } else return false; }}

Page 50: 数据结构 (JAVA 版 )

The

cour

se o

f ela

bora

tion

for D

ata

Stru

ctur

es

www.ytvc.com.cn