Chương 4: Giới thiệu về lớp Mục tiêu bài học
4.3 qui trong Java
Trong lập trình, đệ qui là cách thức gọi lại chính nó (gọi lại chính hàm đó). Trong thực tế, rất nhiều bài toán được biểu diễn và giải quyết bằng thuật toán đệ qui. Ví dụ trong Java, tính giai thừa dùng đệ qui được biểu diễn như sau:
Đoạn mã 5:
public static int calculateFactorial(int n) {
if(n==0)
return 1; else
return n * calculateFactorial(n–1); //lời gọi đệ qui
}
Đệ qui là phương thức gọi lại chính nó. Ở ví dụ trên, phương thức calculateFactorial() gọi lại chính nó. Một điều lưu ý là làm sao để đảm bảo rằng đến lúc nào đó thì lời gọi đệ qui kết thúc còn không chương trình sẽ chạy vô tận và sử dụng hết tài nguyên của máy tính dẫn đến treo máy. Với minh họa ở trên
chúng ta thấy đệ qui sẽ kết thúc khi n =0. Tình huống kết thúc đệ qui còn được gọi là tình huống nền (base case) của đệ qui.
Tất cả các phương thức dùng thuật giải đệ qui có những đặc tính như sau:
Số lần mà phương thức gọi lại chính nó còn được gọi là độ sâu của đệ qui
Mỗi khi phương thức gọi chính nó, máy tính sẽ lưu các biến trong ngăn xếp (stack). Stack là vùng nhớ hạn chế, do vậy với thuật giải đệ qui có độ sâu lớn sẽ dẫn đến treo máy. Trường hợp như vậy được gọi là Stack Overflow (tràn stack).
Phương thức đệ qui có một điều kiện kết thúc. Trong ví dụ trên, phương thức calculateFactorial() sẽ kết thúc khi n = 0. Nếu điều kiện này không có thì phương thức sẽ gọi lại chính nó vô hạn. Trường hợp này được gọi là đệ qui không điểm dừng.
Tất cả các phương thức đệ qui đều có 2 giai đoạn. Giai đoạn thứ nhất được gọi là Winding, xảy ra khi phương thức gọi lại chính nó và đẩy giá trị vào stack. Giai đoạn thứ 2 được gọi là Unwinding, xảy ra khi phương thức lấy giá trị từ stack ra.
Ví dụ dưới đây dùng thuật giải đệ qui để tính lũy thừa hai:
Ví dụ 1:
package test;
import Java.util.Scanner; public class PowerOfTwo {
Chương 4 Giới Thiệu về Lớp
55/114
{
Scanner input = new Scanner(System.in); int power, result;
System.out.println(“Calculate the power of two”); System.out.println(“Enter an integer power: ”); Power = input.nextInt();
Result = powerOfTwo(power);
System.out.println(“Two to power ” + power + “ is “ + result);
return; }
public static int powerOfTwo(int exponent) { if(exponent ==0) return 1; else return (2 * powerOfTwo(exponent - 1)); } }