Những lợi thế của đệ quy là gì?
Một số ngôn ngữ lập trình có thể tối ưu hóa đệ quy đuôi, nhưng, nói chung, đệ quy tiêu tốn nhiều tài nguyên hơn các vòng lặp thông thường.
Có thể có một phiên bản lặp của một số hàm đệ quy không?
Những lợi thế của đệ quy là gì?
Một số ngôn ngữ lập trình có thể tối ưu hóa đệ quy đuôi, nhưng, nói chung, đệ quy tiêu tốn nhiều tài nguyên hơn các vòng lặp thông thường.
Có thể có một phiên bản lặp của một số hàm đệ quy không?
Câu trả lời:
Có, bạn có thể mã các hàm đệ quy dưới dạng lặp. Về cơ bản, nó yêu cầu bạn duy trì thông tin theo cách thủ công mà nếu không thì sẽ được chăm sóc bởi mã gọi phương thức do trình biên dịch tạo ra.
Nói cách khác, bạn cần một ngăn xếp trong đó mỗi mục nhập là một cấu trúc chứa các tham số đã truyền và tất cả các biến cục bộ. Bạn luôn làm việc trên mục nhập cao nhất trên ngăn xếp. Nếu bạn cần gọi cho mình, hãy tạo một mục mới và đặt lên trên cùng của ngăn xếp. Khi hoàn tất, hãy nhập mục trên cùng của ngăn xếp để hiển thị mục bên dưới và sử dụng mục nhập trên cùng trước đó để trích xuất các giá trị trả về và cập nhật mục nhập trên cùng mới tương ứng.
Tôi đề nghị bạn nghiên cứu một cuốn sách biên dịch để xem cách thức này thường được thực hiện trong mã máy.
Đệ quy thường là một cách tự nhiên hơn để nhìn vào mọi thứ hơn là lặp đi lặp lại. Ví dụ, hãy xem xét inorder traversal của cây nhị phân: inorder(left); process(); inorder(right);
đơn giản hơn nhiều so với việc duy trì rõ ràng một ngăn xếp.
Miễn là bạn không đi quá sâu (thổi chồng), sự khác biệt trong sử dụng tài nguyên thường là không đáng kể. Đừng lo lắng về nó nói chung. Mã đơn giản thường tốt hơn mã được tối ưu hóa bằng tay, mặc dù vẫn có trường hợp ngoại lệ. Đúng là bình thường tốt hơn nhanh.
Bất kỳ thuật toán đệ quy nào cũng có thể được biểu diễn dưới dạng thuật toán lặp, nhưng bạn có thể cần giữ một ngăn xếp rõ ràng (tương ứng với ngăn xếp cuộc gọi được xử lý ngầm). Rốt cuộc, nếu bạn biên dịch một hàm đệ quy, bạn sẽ có được thứ gì đó dựa vào thao tác một ngăn xếp và lặp qua hàm đó, và đó là phép lặp.
Các hàm đệ quy đuôi có thể dễ dàng dịch thành các vòng lặp và không cần ngăn xếp, nhưng đó là trường hợp đặc biệt.
Những lợi thế của đệ quy là gì?
Hãy thử giải quyết vấn đề Tháp Hà Nội lặp đi lặp lại. Một khi bạn từ bỏ, hãy xem giải pháp lặp và so sánh nó với giải pháp đệ quy. Cái nào đơn giản hơn?
Có thể có một phiên bản lặp của một số hàm đệ quy không?
Vâng, về nguyên tắc. Tuy nhiên, đối với nhiều vấn đề, bao gồm các tác vụ rất phổ biến, chẳng hạn như duyệt qua cây, các giải pháp đệ quy đơn giản và thanh lịch hơn nhiều so với các tác vụ lặp.
Những lợi thế của đệ quy là gì?
Sự đơn giản. Nếu không tối ưu hóa cuộc gọi đuôi, tất nhiên sẽ tốn nhiều tài nguyên hơn (stack), nhưng bạn sẽ triển khai như thế nào deltree
trong Java mà không cần đệ quy? Vấn đề là chỉ delete()
có thể xóa các thư mục nếu chúng trống; Đây là đệ quy:
deltree(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
for (File subFileOrDirectory : fileOrDirectory.listFiles()) {
deltree(subFileOrDirectory);
}
}
fileOrDirectory.delete();
}
Tôi tin rằng đệ quy là một trong những công cụ mà một lập trình viên phải sống. Với đệ quy, bạn có thể "nghĩ" các thuật toán của mình và giải quyết chúng theo cách bạn nghĩ về nó. Nhưng, tôi phải cảnh báo bạn, mọi người đang nói về sự đệ quy đẹp như thế nào và mức độ đơn giản mang lại cho mã, liên quan đến việc tôi có một vài điều để nói:
Có những điều đó trong tâm trí, học đệ quy! thật buồn cười, phức tạp và nó sẽ đập nát não bạn!, nhưng bạn sẽ thấy mình yêu nó.
May mắn nhất!