- z3 [' `, a: C% b' q; A7 k9 t8 f 关键要素 ( Z$ X6 f$ F5 q" } C1. **基线条件(Base Case)**& l. T t" N" ~. i4 I4 e
- 递归终止的条件,防止无限循环 0 ]! X7 N) c2 E: {' j9 X - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 ' `7 i/ l: K- d5 j+ j; j 4 C* ?* s+ K: @& ~2. **递归条件(Recursive Case)** & X) i3 c0 o+ G1 b# k: t% V2 Z - 将原问题分解为更小的子问题3 l# ~0 [- Y! S! I. ?, N" e
- 例如:n! = n × (n-1)! $ [3 S/ a8 [& L$ B2 d- J3 \0 M & b1 }6 A& _, x7 h! f2 h' F! d 经典示例:计算阶乘 # Y2 E) w% X3 d! Q6 Apython2 C9 {8 _+ `. a" T
def factorial(n):0 _ Y9 }# ]) Y$ W8 C
if n == 0: # 基线条件 # e# Z( f1 Z- `+ ?2 W4 | return 1* `* _& y9 l, \% i7 d \7 ]
else: # 递归条件 $ X6 q0 A6 I F return n * factorial(n-1) ) v3 h) I! v: H执行过程(以计算 3! 为例): & Q& W, y! k9 r* o4 _. [factorial(3) 0 k$ L; w2 `5 X4 C3 * factorial(2)- D$ a3 v. M. `" w7 W0 `
3 * (2 * factorial(1)) * |$ I8 d- c4 g Q3 * (2 * (1 * factorial(0))): {- c3 o" g) k8 }2 X
3 * (2 * (1 * 1)) = 64 n) t- X7 J, d' K% K
9 Z$ e' v/ O. K3 k. J
递归思维要点5 M' O* ~- |. w6 i' o) A5 N2 H
1. **信任递归**:假设子问题已经解决,专注当前层逻辑 ( ~' D% K* }/ S/ X- }2. **栈结构**:每次调用都会创建新的栈帧(内存空间) 3 `+ H: S' m' P# [3 \1 g3. **递推过程**:不断向下分解问题(递)/ q" ^% q1 Q* u- S; L* P( [- P
4. **回溯过程**:组合子问题结果返回(归)$ Y" [# Q: s" [6 v: U+ n* r/ O
) e8 n: s4 w: \! | 注意事项 . K0 W6 p2 x7 N7 I6 p' X5 `1 v6 A必须要有终止条件 ) p4 |& a2 V: ?- {9 V0 G) X/ P递归深度过大可能导致栈溢出(Python默认递归深度约1000层); Y9 X$ J5 k' ~7 r3 n5 Y6 Q
某些问题用递归更直观(如树遍历),但效率可能不如迭代4 j& t3 y" ~6 T' X3 d
尾递归优化可以提升效率(但Python不支持) ; g- P' u& o' `) v9 ?) W/ w4 c* _+ D4 f8 i, r
递归 vs 迭代 6 \; g: W c1 a1 S" q& A6 H| | 递归 | 迭代 | . }" \8 [! F0 F9 B: g: J: @7 s|----------|-----------------------------|------------------| 8 W) E0 G% X. k. e! v| 实现方式 | 函数自调用 | 循环结构 |# J+ B& g3 r U K
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | 6 I* a5 h U s- Q0 F/ s9 J' i; c| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |' m, Z0 j4 g$ L b% f. s: ^2 x
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 | . j( c6 N9 |3 }) u+ f5 ^- X- D E- \7 v# |; L/ o
经典递归应用场景 6 H$ w: M9 d7 T& n+ a1. 文件系统遍历(目录树结构)* K/ E" y; h$ ^! [8 Y U9 D
2. 快速排序/归并排序算法4 c6 J/ P( k( _7 o
3. 汉诺塔问题 * v% \0 s) j1 s9 J" u. ]- f) S4. 二叉树遍历(前序/中序/后序)% L1 Y0 u, o# D, d J( y& U9 W0 W
5. 生成所有可能的组合(回溯算法) ( z4 c6 ]% U0 k* X8 V( @# j8 U& W5 y/ ]6 C
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, $ ^' N2 L1 o+ C我推理机的核心算法应该是二叉树遍历的变种。; y' h6 ^7 w3 z: d' X
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: . C& _1 G* ~, [* K1 H1 TKey Idea of Recursion+ @) X1 R5 h4 ? R
7 K" |7 P K, g: ~A recursive function solves a problem by: x8 `3 O( n2 }+ v; W a7 |( z& {) A, v- r3 C
Breaking the problem into smaller instances of the same problem. # c+ | Z: x0 u" j: O: W) H9 e. i3 m9 v0 z
Solving the smallest instance directly (base case). # }; } i+ @- y: ~0 o% Q/ r : X; h4 R2 Y4 p Combining the results of smaller instances to solve the larger problem.+ v0 D6 e! B7 i- s8 @ F
. C; G6 } s0 l
Components of a Recursive Function& {7 L! X) D/ T: z
& F+ r7 d8 |6 a1 T$ u Base Case: ! G8 H% n: G: b9 w3 z: ?( [( s8 a( V) w/ \
This is the simplest, smallest instance of the problem that can be solved directly without further recursion.% p( B3 b1 k1 Z& R* Q: Y
5 P" r2 _. j% N
It acts as the stopping condition to prevent infinite recursion. & b" ]- U/ C7 A5 T( {9 X4 l- f! @. r$ h7 ?! S1 i& X6 y
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. 1 |7 O8 c$ s! \5 x5 ]* Y) ]- u3 w7 t# T8 E, i7 A
Recursive Case: 5 U! M7 @* O) G8 Q0 t' Y+ s4 c/ E / a6 A+ r2 z S" r9 T This is where the function calls itself with a smaller or simpler version of the problem.- R7 X$ y) {( Y1 B0 l/ E
/ [ `, r' \7 o3 m7 l Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).6 `$ R. S9 ~+ h6 y$ h6 ]
7 m) a5 f6 Z' g+ J
Example: Factorial Calculation / E% G8 R, ]1 y# _4 A$ `2 d0 Q% E' B l/ p7 y% D" M
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:0 C7 D- _+ T* W' o0 V# K" W
9 d8 R+ ~. o, I+ n2 l
Base case: 0! = 1( j/ M& Q& y. H% t
' H1 M1 w; \ K$ j
Recursive case: n! = n * (n-1)! / s3 O* C; }$ z7 w9 i2 \+ l7 i' U2 I( ^9 V3 X) S5 D6 u
Here’s how it looks in code (Python): 3 g8 h9 k" X2 m/ d" E# p1 Y/ {python . e3 ~8 g' h7 q : o5 z1 A k+ c9 `; b0 n4 u7 q/ P/ _8 U) E0 q" R) R: ]. h; y
def factorial(n): 4 l8 B5 \ U' z7 T # Base case3 ^, U$ ]2 t! H* }8 ~
if n == 0:+ ]. }; i( j) b
return 1" C2 f2 {+ x! _
# Recursive case% B1 D1 |7 l" r7 E# D
else:/ R% I- a4 b; y5 G: b+ W
return n * factorial(n - 1). _ F5 v( r% A7 G( g- k
( G3 D. W$ p8 W( S4 n# Example usage 3 _% X% `% B1 U0 `5 dprint(factorial(5)) # Output: 120+ ^0 M* \* A7 S c8 ^* O# |1 K
+ r# B. H4 B/ `
How Recursion Works+ w. u7 d3 v6 t! K
- Y! _! |- x6 n* X8 X+ m9 j
The function keeps calling itself with smaller inputs until it reaches the base case.) q# E* H) f' E; a" r5 O0 A
9 Q, h+ y1 |* W
Once the base case is reached, the function starts returning values back up the call stack. 4 ]/ ~- f$ U i. q 7 R4 p" J$ V3 E: w% G These returned values are combined to produce the final result. - n! W% i7 i6 x2 v& J6 A# g4 u6 A $ q9 K7 r; w6 `% {/ w( z5 WFor factorial(5): h( K) g/ [$ _* b% x1 Z6 Z
, M; L4 L$ A6 h. O! p0 `" R& MThen, the results are combined: / E3 m3 G9 p5 R( P7 W+ i" |5 a * H2 h- {% G( A7 ^/ P8 C 6 O1 q/ m' V' \' R4 y R/ j2 T' Ffactorial(1) = 1 * 1 = 1( c, D3 P/ [" ~0 z8 |/ e
factorial(2) = 2 * 1 = 2 8 \: G6 _0 [/ w- Jfactorial(3) = 3 * 2 = 6 4 m6 D" n( \( j* L b' f* j, H5 Sfactorial(4) = 4 * 6 = 24" R7 \7 `- ]7 B3 G" T3 U) t
factorial(5) = 5 * 24 = 1204 M& V5 |6 Q' @. X! o6 S d9 D& e
/ o o5 ~- v* z$ O2 i9 N8 i7 Y# dAdvantages of Recursion: @9 c' \$ y% A3 v6 C$ J
0 }$ \$ n9 W$ E! O+ A: s" Z 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).9 J G$ r5 y! P: G& w3 f
7 t8 Q0 O1 s3 u$ S, b3 k8 g2 y) A Readability: Recursive code can be more readable and concise compared to iterative solutions.2 u: V; ?7 C5 B8 P
8 c1 V2 g, w' [/ d
Disadvantages of Recursion , D, u. P( Y2 p* Q+ l$ E E# j3 F& _! x9 R+ F 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., ?+ Z( V( Y3 A2 J
+ ~( ]) _" k/ l6 p3 j Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). " s$ l4 t B7 ^' v- ` * U4 g- L' c- u/ a; J* ]3 _4 | N6 tWhen to Use Recursion+ r7 Z- b! T/ D. F; z. X) l
( x: r( ?$ K3 l- w C0 {' K
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).1 r8 M$ K' z1 {& g4 q
, B& |9 Y3 {, r% c# G Problems with a clear base case and recursive case. 7 Y( \# u1 ]3 r: @- T" W% S7 a5 V8 k5 L$ s# H5 Z" @! R- Y; J
Example: Fibonacci Sequence ( k, Z* P5 ~; A# ]9 S6 D* z7 u" {9 j; ?% ^8 |0 h
The Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: : Y4 O0 a% _- @# R* {9 @6 }. h . d" r/ H% ?6 B0 b Base case: fib(0) = 0, fib(1) = 1: H3 F y, `% t" {
7 T+ u. L% G9 ^0 p1 e Recursive case: fib(n) = fib(n-1) + fib(n-2) $ [6 u5 u' u$ |6 p& t3 X1 T- \9 [/ p7 u2 y$ |, G- p, }
python' h0 ~* \' U7 ~7 z% d |
* F( q4 P# X- M+ L f: E
; ?' V) z8 e# F8 z/ gdef fibonacci(n):1 o6 T4 v3 p0 G' K$ X4 i
# Base cases* t* M& V& t1 f
if n == 0: 0 T# S4 n* I; | return 0 + i* j" p* Z. I7 A$ j2 W, D1 } elif n == 1:, d7 M0 E8 S' D3 M( }8 \
return 1% l0 |6 L$ }6 C D4 M6 A% m
# Recursive case 8 x% x7 n( Y8 ]1 J* N! b' e! T else:# Q- \: I/ ]7 N$ K% ?
return fibonacci(n - 1) + fibonacci(n - 2) 1 r" x% [3 @7 v+ n% O 6 g y' [1 x7 h; O) m0 n. X* |# Example usage $ h( W+ t) O9 {4 lprint(fibonacci(6)) # Output: 8: G% Q9 S& T$ j g5 A1 w) z+ B$ p+ U
' w3 `% }% a9 M$ t6 Z3 G' ITail Recursion / `+ r0 r+ d- W, k: \ 5 s! z9 {/ c+ z+ {' I1 A lTail 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).. F2 \& t% _* a( t/ u% `0 j5 _# L& l
8 T6 b* P$ j. v' v3 GIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。