: c. ]. e( T& b$ S/ V 关键要素 7 c, C; z9 g. d d1. **基线条件(Base Case)**4 B: [/ ^9 j+ u/ v5 G8 f; ~
- 递归终止的条件,防止无限循环, [( P9 a& k, k7 E- A5 A4 r
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 # c% G, j! }+ }' O k; I1 Q; o2 Y
2. **递归条件(Recursive Case)** - `5 t6 W- w1 ]: ~: U5 D, [( c0 @. h - 将原问题分解为更小的子问题 ( F$ d$ b! N- l4 g% p - 例如:n! = n × (n-1)!, L* U6 c* W) F) T6 E' s
# p$ l1 G3 j8 Q, c
经典示例:计算阶乘 ( a" D Y5 G$ m0 m- J+ c) R, Q- Vpython 4 i+ c0 x9 z0 j$ E6 xdef factorial(n): & k" b& H n0 ~: O( P9 C5 A2 ^ if n == 0: # 基线条件$ m! W7 @. ^% r0 r0 L2 d
return 1 " [) e) \( _7 W- E$ H4 q9 j else: # 递归条件4 e) ]# X7 j3 j1 ]8 l
return n * factorial(n-1) 8 D: x2 K1 m3 g3 |4 Q; X执行过程(以计算 3! 为例):* V4 `9 C" q$ a
factorial(3) % s4 u% Y6 e# |8 ~" J' \3 * factorial(2)9 k. G7 o1 f2 ~ J& d
3 * (2 * factorial(1))6 Y% Z- H$ F5 U2 n* X! g
3 * (2 * (1 * factorial(0))) # R6 b) k3 O3 Q! ?. E4 ~3 * (2 * (1 * 1)) = 6 ( z' ~# \, _: H7 ?1 w5 M) K, `: o) X" r% G8 r
递归思维要点7 J8 l6 ]" ~4 I4 @5 ^
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 5 ^& S; c. S! T$ y2 k2. **栈结构**:每次调用都会创建新的栈帧(内存空间)# b. P) M/ M! X6 s' U
3. **递推过程**:不断向下分解问题(递) " Z/ W! J2 ]$ @' _* U K4. **回溯过程**:组合子问题结果返回(归) 5 r0 H3 E6 B+ n F" l7 r( P [- K( g0 u5 a 注意事项 6 X9 M% N- V8 p# Q$ S必须要有终止条件* n5 a1 T+ z& |4 U7 ^' N. T
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)9 | H( D+ V7 T% k6 o& {$ Q
某些问题用递归更直观(如树遍历),但效率可能不如迭代# _1 N8 P9 _3 w$ w0 J+ M* @! m
尾递归优化可以提升效率(但Python不支持) 2 {& ?! O! U3 E& S; W 3 u2 W! j$ W1 h/ K% ?# S- x) G U 递归 vs 迭代8 c! c& {! }! Y* d$ D
| | 递归 | 迭代 | g; d7 Z5 w9 K|----------|-----------------------------|------------------|7 _ u% e5 C8 B3 `- v6 c3 c
| 实现方式 | 函数自调用 | 循环结构 | ! b: w+ @2 G+ q F4 \: O( Z| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | , L6 J9 b D! G# ~| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |% e7 o6 R; x) ]8 B) S- L* r
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | 2 }- S" c6 l3 J- p G' g4 d1 B+ ^9 \
经典递归应用场景$ ?8 d6 R) ~( Q+ n( I
1. 文件系统遍历(目录树结构)6 u. E. Y8 F: j/ i7 {2 R" z3 h
2. 快速排序/归并排序算法 " a7 A$ g( K& U/ u3. 汉诺塔问题! V, E0 Z, m( G
4. 二叉树遍历(前序/中序/后序)" o: h: q$ }7 H7 W% F( \
5. 生成所有可能的组合(回溯算法) * k. t' V2 d( O7 C# g# l7 u2 M" U0 M; T
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, 9 E0 u- n1 z: R我推理机的核心算法应该是二叉树遍历的变种。 9 W' E$ V6 l$ l4 i$ G9 `0 R( Y另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: 4 l' `. e \+ F9 m' rKey Idea of Recursion 7 V) a0 Z1 P% e0 r! k; E# P' E0 k + {5 W" g& D% `% kA recursive function solves a problem by:3 O. W! z: [$ \" B/ ?2 K0 k
/ T1 O8 L$ G+ W3 j5 @! m# w Breaking the problem into smaller instances of the same problem. 0 k+ x7 ]6 m. C3 | * @$ m. A$ B& b' ^$ S7 J Solving the smallest instance directly (base case). 6 f7 v: \5 r( L* n0 ^9 m. E0 S' i- @8 B1 i
Combining the results of smaller instances to solve the larger problem. 5 Y3 x2 g5 m4 D p: j2 y3 E 3 v" A0 ?2 |# t6 ~4 oComponents of a Recursive Function 8 |' W% S! c+ r0 W; q7 [! Y2 L& X" {9 y# i
Base Case:5 z( `% [. c- L, z, y
% b a0 Q9 Z7 i) z7 y0 `+ w4 d
This is the simplest, smallest instance of the problem that can be solved directly without further recursion. 8 Q% I2 q' E7 Z9 B. O6 S& r% b' Q
It acts as the stopping condition to prevent infinite recursion. * M3 p6 \% T* m9 l1 d# W5 n0 T 6 ?/ @! ~% S; D- }0 L1 l Example: In calculating the factorial of a number, the base case is factorial(0) = 1.$ A2 Q/ b5 z1 j5 L9 d! T! \
% M3 z! h3 @( f) l; I. D4 l
Recursive Case:0 q' `% @0 B6 m9 J5 ^
7 T, X5 w6 B/ s" y, h0 C
This is where the function calls itself with a smaller or simpler version of the problem. * l* N3 N }3 Y, ?" r1 g# b& S' k: F! l7 s1 v
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). 0 X2 x; W' y" y+ `6 D . Z1 k7 X; u2 [( q& q6 jExample: Factorial Calculation: D' T9 c! l# J( X( M' S
# ]: G; p" T2 Y) c3 eThe 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:4 q, r4 o9 h+ b2 Z* ^
" Q" F3 s: l5 N* q( v, B
Base case: 0! = 1 W+ i* e# _4 \1 x8 q& H2 [/ z4 u0 H7 W9 N0 Z8 s q
Recursive case: n! = n * (n-1)! ( f5 q5 n5 S: A1 C * X! I2 ?, j6 k/ NHere’s how it looks in code (Python): ' D9 A( r5 o+ c; O: Gpython' Y: h/ m( X& A* u" f& u
* J; e, S! c. n7 F' Y+ O& X
" D! F6 k+ \; v3 i0 \
def factorial(n): 2 |/ P* U, x& C" k% A8 C # Base case 2 y* w1 A6 A( S2 T; U if n == 0:2 G4 c5 U( u; n1 n
return 1 9 a: P. f; e8 ^$ A# W# K # Recursive case6 w. ?" v1 ^" O: c$ M" A6 X
else: + a% I5 s5 N4 U return n * factorial(n - 1)! t# j2 ^; A0 @2 j+ |! }
* e: ^- R( E; d2 }/ n i4 | The function keeps calling itself with smaller inputs until it reaches the base case.9 o+ p9 U7 P6 F* l9 s, R6 t
2 {. [" C5 s. y3 k Once the base case is reached, the function starts returning values back up the call stack.7 a+ U5 X# T! @/ \
+ n! D" f" Y5 K8 I' X; _
These returned values are combined to produce the final result.$ Y- Q4 k% t- V+ U+ V7 x3 Z, b1 U
3 u5 r0 m$ Z! _! S; o) [, IFor factorial(5):% B- m# y( l. r, l! P V
. \& f: s0 G) {" B2 y$ V3 ^# F * i$ i7 b5 m3 B- ], Rfactorial(5) = 5 * factorial(4) k4 R" z7 _8 l' f" r, h
factorial(4) = 4 * factorial(3)) V& X* i" g( _" | o6 K$ u
factorial(3) = 3 * factorial(2) 7 b* M. K7 |% N& U9 A8 Jfactorial(2) = 2 * factorial(1) , x& Z; {! w) ~% vfactorial(1) = 1 * factorial(0) ( ]. c! Y8 x1 K) tfactorial(0) = 1 # Base case : v, ?! ^. }8 ?% q: _' U! f* h1 U
Then, the results are combined:2 T4 X8 R% L" n9 }" S
# D' U/ Y/ h6 U. x5 d( Q 0 b& V+ {# M0 K- T* k# pfactorial(1) = 1 * 1 = 1 8 p* `7 @, I0 i, s$ f" i7 T* n0 x# M% ^factorial(2) = 2 * 1 = 2/ \- Y# {4 B8 |2 e# m# L
factorial(3) = 3 * 2 = 6( u2 c; i, l2 b+ B: z, b( ^
factorial(4) = 4 * 6 = 24 1 L* @: b' V9 }2 rfactorial(5) = 5 * 24 = 120 + X- U0 J# k' k5 K5 j ) n* V/ r! |! J9 GAdvantages of Recursion 5 _6 |3 P: _2 s) E, a1 x1 t1 o% V* y" w7 G6 c: O
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). 5 r2 K& e4 r' f! d- \ % o# f& v8 [0 l4 K Readability: Recursive code can be more readable and concise compared to iterative solutions. 8 V) G R3 x# B) q3 N # r+ u1 r$ |0 |1 R* ?3 {) |Disadvantages of Recursion/ i; M1 C. u- y# ?/ R7 M. k
" y" ?7 G! W& F/ E: k- k+ K# S
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.$ e* x) x: m0 U. n
- k$ A) ]. F/ o* y0 A& p$ ^2 C
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 6 a, P* Q. Y2 n. h8 s) r4 [; k' b* [! F' y* X7 b' y8 g' o
When to Use Recursion6 @8 n0 W. W9 ]0 g8 A3 j
. W( b6 Z! K! W$ J1 f( ~. c8 _
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). # U% Z w/ n7 u( x6 N ! Q( p- M. `4 {1 }' { Problems with a clear base case and recursive case.& K& V3 c8 P8 ^9 F
" T [" D ]* c; ~: m$ V7 yExample: Fibonacci Sequence' t% Y% I. J; D2 m8 Z# a
3 j' ^7 @/ E" ?$ f6 @. E. V* J3 ~The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: , f' E0 P0 ~' h9 P( n! X9 N1 {, f4 c! o3 J! D- k
Base case: fib(0) = 0, fib(1) = 1# \1 \4 B3 G; j+ B8 q1 d
* {) a5 q' K+ C' W1 o Recursive case: fib(n) = fib(n-1) + fib(n-2)7 ^9 |! H( Y. m) {
5 x# c* e" A! f% f3 Fpython0 Y% ^# e* B1 i( O+ B- R
5 }! X p6 L8 ?% F9 J
% T q3 t9 \8 @& d; m
def fibonacci(n):& ? O8 N% r% k& j6 G' \
# Base cases/ x7 ]" W" U6 D7 m
if n == 0:) O) o5 P2 W5 ?4 J" X* m1 U
return 04 C) ~; F7 P' x$ v" L) N1 A( r) |: Y$ I7 C
elif n == 1:1 T* Q: @ U: I
return 1# W4 |. o4 y7 C' ?4 }2 L! i4 E
# Recursive case 4 y* i3 ?/ |( v7 Q' { else:* J; H6 d: c* z
return fibonacci(n - 1) + fibonacci(n - 2) 9 F0 ~$ Y5 b2 @) H& s$ O) e3 R( N2 a# I4 O8 l& v/ }
# Example usage 7 z5 x- S( X Iprint(fibonacci(6)) # Output: 8 ( ?: H# A% K' ~' A7 t3 [ 5 H' E E; F* W$ dTail Recursion * w' N. @- _# j0 y( J0 O6 M( m- a% y, _! v
Tail 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). + W% _/ Z ^( P5 h& C2 S/ t& U. a! Z& }3 M; S6 c+ f; `
In 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 现在的开发流程,让一个老同志复习复习,快忘光了。