3 s* N# R' }0 F: x2 V7 F递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。- t2 H4 |' \1 Y0 V6 z( h. v S
: h# J a* c8 \ 关键要素' N, X9 c1 b0 w- m
1. **基线条件(Base Case)**8 w; ]2 x1 p7 E) j O* y1 G1 O
- 递归终止的条件,防止无限循环' W l! `+ e. y8 N0 \$ {. p
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 2 v/ c6 w2 @ a' m 2 [3 K, t# R9 a3 Y5 H7 {4 b4 S, @8 A2. **递归条件(Recursive Case)**7 U: ~6 P( {8 }9 c* i# r+ |, v
- 将原问题分解为更小的子问题 , f( B8 P+ f8 M8 u* I3 v/ x - 例如:n! = n × (n-1)! % S% n- n" k( a9 K) V$ c( M; b% }8 l* j. [
经典示例:计算阶乘8 D, |; }" Q/ w0 w
python ' R+ Y8 X4 j. B7 n' g6 y; Udef factorial(n):+ B: ]( J8 T' y! |
if n == 0: # 基线条件 : {% R9 p! X2 c' g8 k return 1 & {. O1 X6 Y3 @6 [/ b5 g else: # 递归条件/ K7 \6 `* Y( f
return n * factorial(n-1) . C2 E2 c3 l" r执行过程(以计算 3! 为例):; ?2 O+ i; U! t
factorial(3) " Z) R+ }- f# B3 * factorial(2)2 Y; U' \) k% e6 S ^, k4 e, |
3 * (2 * factorial(1)) ! }6 k3 m7 G, p/ t3 * (2 * (1 * factorial(0)))/ f- z0 A( F( d
3 * (2 * (1 * 1)) = 6 / P K6 i5 C z, j7 }7 @2 s9 R/ N3 `: i
递归思维要点- L8 q. Q: O% A! I% K2 b
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 " a7 q+ @5 Z0 }1 v: p/ @2. **栈结构**:每次调用都会创建新的栈帧(内存空间) + D- b4 P$ g$ B) W9 v; X0 B3. **递推过程**:不断向下分解问题(递) }- |5 t, k2 W! \
4. **回溯过程**:组合子问题结果返回(归), O/ T" n1 ^: ~! M1 T0 C& l3 [$ u! n
2 T1 Z" {& P, O( _
注意事项 . i8 v/ E5 Q j4 @* G必须要有终止条件; S5 f/ R2 s/ e: @
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) " @4 y# q1 A# r某些问题用递归更直观(如树遍历),但效率可能不如迭代7 Z S/ K( H2 i7 s
尾递归优化可以提升效率(但Python不支持) ! V0 `4 L6 H+ S; e* \& V% z3 m& W; m" i* {; l4 c
递归 vs 迭代 & l$ z+ ?1 g$ i* a$ O; Z! i% i| | 递归 | 迭代 | 1 \1 c2 E, c; S- a|----------|-----------------------------|------------------| , A: _; x( b4 C1 q) P9 t, l| 实现方式 | 函数自调用 | 循环结构 |/ d& ^1 G0 i9 ? D' Y
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 |1 H0 W+ J/ E2 [/ v
| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |, G& K$ o; I& N8 }4 d# g( N
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | X: l6 t9 ?4 V2 Y+ U/ l4 E( ?0 W: |- m' G# {1 Y( J# Y0 R
经典递归应用场景+ S1 i$ Z2 Q5 H4 {
1. 文件系统遍历(目录树结构) ) R3 f }& }5 y& z2. 快速排序/归并排序算法& u2 R# m* k- w q$ C/ {
3. 汉诺塔问题$ l( c% [; s) ^& P, N, N8 B7 T' B7 W
4. 二叉树遍历(前序/中序/后序)" d) z- R' L3 s" U% L& I8 M5 \. q
5. 生成所有可能的组合(回溯算法) % y" }# ]9 D, u7 T) C9 i4 C1 z # @8 i! D* P8 \) d1 i" L试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, 3 Z8 h" f" L6 K* ?( s; z我推理机的核心算法应该是二叉树遍历的变种。 + M, E+ p' n0 a/ Z0 ~: n另外知识系统的推理机搜索深度(递归深度)并不长,没有超过10层的,如果输入变量多的话,搜索宽度很大,但对那时的286-386DOS系统,计算压力也不算大。作者: nanimarcus 时间: 2025-2-2 00:45
Recursion in programming is a technique where a function calls itself in order to solve a problem. It is a powerful concept that allows you to break down complex problems into smaller, more manageable subproblems. Here's a detailed explanation:7 Z& f! _* ^7 f
Key Idea of Recursion. v2 f9 n. u3 m6 `
; v' o: ?- J: \( ^0 h" aA recursive function solves a problem by:0 e2 Y) o1 r2 K5 e# E0 `+ e
1 m6 x1 N: p; P- R
Breaking the problem into smaller instances of the same problem.6 M. ^1 _' v# N
$ h' I0 ~0 l& [
Solving the smallest instance directly (base case).0 v- F6 {1 m* w r' k- S
9 K2 ^- T; { x8 W* S3 Y |! ]/ D: B Combining the results of smaller instances to solve the larger problem. 4 ~8 R% R* q/ Q. O, J! Y $ M% ?% E2 F! {2 X' TComponents of a Recursive Function" G* R0 l- F( \. P' o
J, S6 W% `, A+ S7 t- D5 U i
Base Case: . A; c; j; ]' {" K* k; a& Z' ?) C 9 }: f) b# l4 n$ v4 h8 w+ x This is the simplest, smallest instance of the problem that can be solved directly without further recursion.5 z+ o, s9 W( z
8 A& K: p( h. O* e2 ]$ V: P' `6 k. @ It acts as the stopping condition to prevent infinite recursion.+ {# b$ U1 R. i2 o- e' ^
' \; d) j, H8 R+ w0 q
Example: In calculating the factorial of a number, the base case is factorial(0) = 1.& _: _4 ^* p1 E4 D3 o
9 R7 K# r' O7 ?+ a; C/ s7 x' U
Recursive Case:3 L2 f: m1 @" h8 C6 ^+ e' i
5 V- M0 t1 i* A8 p8 @0 C! r& ^5 w This is where the function calls itself with a smaller or simpler version of the problem.8 ^4 f+ ~7 {( H3 r
% L( k8 v [: b" @! R4 l3 V# b# g1 c Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).* z5 f8 K; u7 j
: N& F7 F+ X) U) O ^* _
Example: Factorial Calculation 6 v) C8 t. C- R) ^# W6 e4 Q. L2 x P6 T2 J
The factorial of a number n (denoted as n!) is the product of all positive integers less than or equal to n. It can be defined recursively as:7 r2 Q* K) \! {: V
" _4 G& O6 t; r% T- T. K Base case: 0! = 1 9 w$ g+ T' }" P; N. V: e% p ' |1 s' y3 \/ C Recursive case: n! = n * (n-1)!2 H% k; j/ ?$ {0 ~" a& f
x, h$ W( q/ | B
Here’s how it looks in code (Python):, l* _+ U) V# Q* Z
python3 Y9 R% G# S0 _; }8 L
: \- J9 K3 i1 b
8 a2 U6 A3 W: L" s" }6 w
def factorial(n): % ^$ q/ j+ I; s" [ # Base case % _$ q3 h4 q# w# p4 B if n == 0: 2 r" z: s s# c return 1" N. V: C' Z k& S4 Y& R
# Recursive case . u8 S" m$ h: n' L# S3 w+ V+ g7 | else:- T4 X, r b$ ]+ V9 K9 Z8 i
return n * factorial(n - 1) 8 h+ e) l2 `# r$ _+ @4 @( S: a! P9 A. h J# y: B2 K% |
# Example usage : c% G7 }( M( rprint(factorial(5)) # Output: 120 9 ~5 ?. }% ?8 L) V* K . i% u: R; N0 {2 OHow Recursion Works $ t7 j3 V: J6 }2 X/ ?4 P) w3 E$ [+ {+ z% {. N
The function keeps calling itself with smaller inputs until it reaches the base case.( q- l/ @! S% ~9 g( k& o# W& ^, l
7 Z; Q4 b2 E E
Once the base case is reached, the function starts returning values back up the call stack. r: o* C+ ^* n" M# f% P$ g& Y1 E! e) O* c& `/ M( D. K! [
These returned values are combined to produce the final result. . R7 M9 n( c: B: N # ?4 T$ l4 D4 |% {; z# XFor factorial(5): 2 @2 Y* i* G: z* w/ ]: f 9 i9 U1 i4 T6 T6 c & t2 ]' }3 b0 U& K3 p; Efactorial(5) = 5 * factorial(4) $ }, X" m8 r8 S' p1 Rfactorial(4) = 4 * factorial(3)' \! o8 h0 f5 M
factorial(3) = 3 * factorial(2) # V4 r0 ~0 [& Qfactorial(2) = 2 * factorial(1)" n' U( a1 B- O! z, L
factorial(1) = 1 * factorial(0)$ C1 P. p; S) a9 L" r
factorial(0) = 1 # Base case 2 D" J7 h% Y( y7 b) T- y: ^: Z- W1 y9 `2 M, Y W. r9 ?3 }1 E0 [
Then, the results are combined:$ W3 n# |" B0 ^, y# ^
7 d3 O- N i+ r' p+ S& H
7 w7 \0 B" h1 G9 u! n# A3 Lfactorial(1) = 1 * 1 = 18 k% z$ J7 e- n9 {1 Q7 z
factorial(2) = 2 * 1 = 2" J; \ e4 `- S S# ^9 H
factorial(3) = 3 * 2 = 6 P1 I# a9 [$ ?2 p: X. r3 }* U V
factorial(4) = 4 * 6 = 24 * Q) \$ j6 ]* ^5 w" e6 X, i+ J; Q" ufactorial(5) = 5 * 24 = 120 " n4 x" e6 C5 s$ H7 l7 l/ M% D+ X& U4 R" g# R
Advantages of Recursion - I$ _/ Z0 X0 p6 Z C. e% `5 [- }, P; g
Simplicity: Recursive solutions are often more intuitive and easier to write for problems that have a natural recursive structure (e.g., tree traversals, divide-and-conquer algorithms).4 e3 o4 f) m- r$ R
8 u+ \* w7 z2 Z% H
Readability: Recursive code can be more readable and concise compared to iterative solutions. / R$ q# V, n. r, V / W, T w3 E# a+ A% SDisadvantages of Recursion; ?5 H& n W; Z
! f' H, p0 D+ v' H1 Q
Performance Overhead: Each recursive call adds a new layer to the call stack, which can lead to high memory usage and potential stack overflow for deep recursion.: l* ]0 B' C; p4 i1 `
* Q- R" W% _$ |+ G) t5 {
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 3 t- u9 \6 m( U5 S! R# x4 R! v- R: _9 H
When to Use Recursion : c5 }2 M% l$ g$ f- v) ^5 \4 C1 q1 Y: j% }8 K9 n( V& s
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). 2 i6 ^% p1 l+ O3 a' V5 ~! z3 H4 G% S% ~/ M) C: B
Problems with a clear base case and recursive case. % B: n( ^/ ~' a$ T! G' h( z! n 1 p7 K' l x9 L3 kExample: Fibonacci Sequence 2 P# f2 _2 K! |4 C' E" x4 n) Z 0 t4 `* u1 W: l: H2 jThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:7 U$ ~. \) A, M: [7 a. k* z
$ N! ? k( V* }9 y3 M' E Base case: fib(0) = 0, fib(1) = 1" Z; M- W3 a9 n) D2 x: }
8 F$ k2 d6 | q+ h- }7 D
Recursive case: fib(n) = fib(n-1) + fib(n-2) 1 {6 j1 ~9 q7 z5 g; X% I: P 8 \' _- L2 ?- S% S: c' g3 O' i3 Xpython/ {8 k. I& L! {
# ^6 C$ V# o# J5 V# k" g0 @7 ~" B# m5 ? - E7 j& E6 l% s. G/ S- m0 ?9 Cdef fibonacci(n): 3 P% ?, T6 ]5 c; r8 ?, N # Base cases 1 n @: D4 X/ {( @# j. r if n == 0: / [, B0 [ ~% x return 0 3 g. f5 ~. T. C! j) L elif n == 1: & |6 N6 D+ J/ b" V8 r3 E6 g$ Q9 M/ T return 1- r) e+ O5 ^3 ?. L) \; H& W
# Recursive case * ^8 }" S3 P+ Q% X# G% h4 G else:$ Y0 @& V7 f6 o+ z& K0 d0 h5 s
return fibonacci(n - 1) + fibonacci(n - 2) ; X4 ]* e6 m+ E, Y & e E/ n8 v) @1 H4 h. e# Example usage* S7 ]5 a$ N% r, `& N& e: O# f$ h
print(fibonacci(6)) # Output: 8& V0 a2 v, A. x8 j" ~
& F7 ^5 j% Y2 cTail recursion is a special case of recursion where the recursive call is the last operation in the function. Some programming languages optimize tail-recursive functions to avoid stack overflow, but not all languages (e.g., Python does not optimize tail recursion).& m' [9 U* B" L, G: C. U$ M" V
N9 L" ^$ N; }4 wIn summary, recursion is a fundamental concept in programming that allows you to solve problems by breaking them into smaller, self-similar subproblems. It’s important to define a base case to avoid infinite recursion and to understand the trade-offs between recursion and iteration.作者: nanimarcus 时间: 2025-2-2 00:47
我还让Deepseek 给我讲讲Linux Kernel Driver 现在的开发流程,让一个老同志复习复习,快忘光了。