h1 B4 E9 C7 S* B5 h解释的不错5 S" C) C9 t+ } J1 \, K1 T
' ^$ D7 r7 [4 r. n; x5 F/ P
递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。( n' k' I: X: r# x& d) g4 i6 Q, ?# w" ^
' E7 Q' d2 D; W9 j) u0 q 关键要素 \3 |$ q0 F1 E" Q) w( v
1. **基线条件(Base Case)** 6 N3 c: Q3 c- U7 C2 i A: U( V! H1 V - 递归终止的条件,防止无限循环/ `6 \1 ]7 @0 J. F8 {
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1" Q( `' R0 b& Z9 R. R- I
3 Q/ p4 Z" M# m. `8 A2. **递归条件(Recursive Case)** 1 ~ Y( V3 m- v3 R E4 z - 将原问题分解为更小的子问题 6 g/ `3 U/ y. N+ U - 例如:n! = n × (n-1)! 7 b$ o8 P8 Y6 s8 P, \, |! o6 Q4 V3 N* _0 y1 @
经典示例:计算阶乘 . W# h; p7 F* Cpython1 I3 h n7 s3 s9 C. R; T+ D
def factorial(n):( ^2 g$ B8 i- z6 ]9 e! ~
if n == 0: # 基线条件 - F- D, r3 r1 ]( x2 G; Y return 18 h- ^* {, H$ @/ j3 b
else: # 递归条件 5 |' _& {" J8 h1 y+ e return n * factorial(n-1)8 d; ^; L# d N
执行过程(以计算 3! 为例):+ z$ U- ~ G$ ^* ]- a0 b
factorial(3)3 h2 Q( E& h# i7 q! T2 A3 C) b$ j0 M
3 * factorial(2) I& @/ ?8 B2 |3 f* s3 * (2 * factorial(1))+ Y+ B) A( | {4 Q6 b1 C0 }$ T
3 * (2 * (1 * factorial(0))) : P( d5 w0 j+ t; ^% }' q4 I* t3 * (2 * (1 * 1)) = 6 k1 z/ P+ Q+ S3 v; [
. h1 @5 a8 [1 S0 P0 I 递归思维要点, h, f+ M4 y+ I; f6 d7 Y& y. b" \! m
1. **信任递归**:假设子问题已经解决,专注当前层逻辑" Q* a* k' ~6 M! `1 ]9 H; f
2. **栈结构**:每次调用都会创建新的栈帧(内存空间)" v" Z1 O1 @. e; ?
3. **递推过程**:不断向下分解问题(递)/ ~: s: ]. s0 ?
4. **回溯过程**:组合子问题结果返回(归) ; A6 t9 J H0 G5 m% m9 H( q, g! ] 3 I; r7 ` }2 X6 K0 g 注意事项 9 A+ P& V2 U0 t0 E+ m必须要有终止条件 % |$ R) X' e5 v" h9 T) ?2 y递归深度过大可能导致栈溢出(Python默认递归深度约1000层) ' w/ c4 m$ J' r1 u. ]( o7 A9 a某些问题用递归更直观(如树遍历),但效率可能不如迭代* y8 S+ f( R5 r: V# W4 ?
尾递归优化可以提升效率(但Python不支持)/ _0 w: w: p7 N/ t; [) Y
8 f/ ]5 M) z' N# P* b* e; e/ H
递归 vs 迭代+ o' h. ~. N5 m; h
| | 递归 | 迭代 | E" u5 P- w# s|----------|-----------------------------|------------------| % o* G3 n. K( H; J' ]2 D| 实现方式 | 函数自调用 | 循环结构 | # M+ O& D- R; @5 z* t) \. s* k| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | / i+ C2 k2 Z) I9 \1 y8 a$ R0 c| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | $ `. p' V% Q% t& L2 A/ G) ~( t% j: r| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |4 Q1 N! a W/ q9 k3 m Q" j
1 b( x. p6 Y: F2 {5 k0 f/ F
经典递归应用场景 & W: G7 }2 q% h: Z1. 文件系统遍历(目录树结构) 3 V; a7 {4 \$ h# S/ n: Z; ]7 v1 q2. 快速排序/归并排序算法( Z% \" o/ G, \
3. 汉诺塔问题 ) o3 [' x- n# [% e4. 二叉树遍历(前序/中序/后序) ( t0 {/ x2 ]+ q5. 生成所有可能的组合(回溯算法)4 w- k8 O6 o: J. G
/ @# c% ^, N4 h& ~( s, b2 O z
试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒, * A$ a2 t# m# s/ M- z" n! m我推理机的核心算法应该是二叉树遍历的变种。 ) i) r/ T% A- o9 u8 l/ x2 j另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:) M8 f; I: U8 R B
Key Idea of Recursion 3 M1 r- F5 N* [! T2 J( F5 l& y$ _6 B& ^1 y2 X* L
A recursive function solves a problem by:; a" S) T' _1 Z4 s' A8 r
5 Q7 _* q3 k1 X y% L2 \- Z7 J Breaking the problem into smaller instances of the same problem. % Y: }7 p: t/ z$ _; E2 e' c3 T7 v/ R1 v$ Y8 g$ F
Solving the smallest instance directly (base case).7 I) R* v+ B% h* D
8 F! _2 z; t8 Q/ s3 ^& O Combining the results of smaller instances to solve the larger problem. ) L. I6 r2 ^/ m5 U" V; m1 V0 b. n! \% Z5 o% a9 ^
Components of a Recursive Function# h# n* r! t3 M4 m1 E) s
& V- l) d! ^% m9 u5 N
Base Case:* r# }) W2 o3 [% k- R
9 N: z: O. r2 F# K$ P) s, V This is the simplest, smallest instance of the problem that can be solved directly without further recursion., b( F9 X x9 v; L
: |5 F" W6 F4 a& \/ I0 c# x
It acts as the stopping condition to prevent infinite recursion.9 I, ?6 R* U) t* _% F" i. O& E
% x7 X5 A8 V1 J3 A4 r9 U$ ?, \
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. ) e# Y( m' x; w2 p: f! u3 \8 q! J3 u' A+ G2 u& N/ g- E
Recursive Case: 8 j+ J* ~9 X( z + I+ A0 E% l( V; m This is where the function calls itself with a smaller or simpler version of the problem. 5 X! V8 {+ W" X' {/ ?! Q0 o: f; [7 S+ }$ i9 d
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1)./ X& S$ n1 [3 F( v" ~: o$ ]* }2 A$ Q* }$ U
5 a$ T4 k* u% h3 B4 u5 F/ cExample: Factorial Calculation / v) M8 k M4 q$ m3 j5 E; R z! [2 e) f e: 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:5 C$ g. P6 e* g8 T% k, I9 P {
5 K1 e$ r( U s! @% W9 w2 N* Q' {, r Base case: 0! = 1 ' T# V" |- p) Q. W3 {1 s. V s# f3 T3 @8 A
Recursive case: n! = n * (n-1)!' _* `# U& {6 C, g2 w( g
; v5 C# R8 b8 T! c. AHere’s how it looks in code (Python): * ], B0 T r- e* ]2 bpython ) D; N8 [5 U8 o . T- F: k0 A; R/ N' K4 {# c$ F' F# s& `
def factorial(n): " i/ j. J- h ]% `+ v2 i$ P # Base case 5 S( e5 s& `$ }7 E' x( ]* G0 k if n == 0: 9 v [$ v- |8 Q7 i$ G5 K: m return 1' J/ r, r$ S) K7 k& B! U! v
# Recursive case $ b2 |6 D5 S% t4 k& O( f6 ^ else:% b% @' O1 ]3 ~
return n * factorial(n - 1) 2 R R6 L% F$ \/ f5 |" o7 M. ^. Q- w& C1 H0 d8 j5 p V4 Z
# Example usage6 x# U; H3 B' C: T# Y- w/ I2 ?
print(factorial(5)) # Output: 120 " b, M: V" `8 G( P! v& _$ I: a0 _. [1 w: ?# v3 a; |) n
How Recursion Works , w3 w/ D. z1 ?1 O0 O! P4 ]/ V# l. ?& I* Z) m9 |
The function keeps calling itself with smaller inputs until it reaches the base case. 9 \+ f$ u& c1 W6 [) o: w/ t * a/ |. i& G( Z* Y5 h2 K& _ Once the base case is reached, the function starts returning values back up the call stack. # c8 U4 b9 u5 X- d9 w; F* M+ V$ I) ?5 K5 @% E8 w* h
These returned values are combined to produce the final result. # n& o: A3 ~ |: p 2 R# ^8 `- p) C& wFor factorial(5):" i# m# G( ?7 F1 R4 G% ^
' R; [- h1 e J& f5 w
- ?3 \! { C0 mfactorial(5) = 5 * factorial(4) + m# K/ }% S! L# gfactorial(4) = 4 * factorial(3)6 N8 I) z. G$ ~: A! p
factorial(3) = 3 * factorial(2)- m8 r9 |+ k* A2 r9 O
factorial(2) = 2 * factorial(1); D, S/ |0 @$ b. P4 i! e! N
factorial(1) = 1 * factorial(0) $ P) f: {/ c; ^3 c% ]& Zfactorial(0) = 1 # Base case 9 a5 d+ l% N) F/ J% u) z# E * }% D% [! E$ J2 l& BThen, the results are combined:8 I3 ?7 D- _" ]: W" f- r9 P, H) X
/ X* G. g( O7 d9 E
) L) A0 m$ y( ?. r" A9 tfactorial(1) = 1 * 1 = 1 1 F/ B# B; N4 j* \5 O8 @( Tfactorial(2) = 2 * 1 = 2 & {# T) d- I+ _+ Tfactorial(3) = 3 * 2 = 6 1 {" W: m9 F# B8 I) i8 f; ifactorial(4) = 4 * 6 = 24 9 f& R; d; A o( q( V! Ifactorial(5) = 5 * 24 = 120 : a+ \1 h4 }3 Y" t4 \ 7 [7 y2 y. ^. `! _! J% j) O6 bAdvantages of Recursion $ ~+ f2 x. s' i: N6 H ! [4 C3 k4 q9 M7 D+ V- p7 J( f& N 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).( C9 Y* }& Y) \0 _
* e* G: M! B! g Readability: Recursive code can be more readable and concise compared to iterative solutions.' d# _! j3 Y2 Z# f( |' |3 d4 `! q
: Z( N2 n, D+ Y
Disadvantages of Recursion0 w, ~- x) `% {) G5 }" s
) S3 S- p4 l9 ]+ X3 T7 } 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.# S B7 W! P3 E
9 t* C5 I+ m. N0 M2 c Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).- E, y3 N( A$ m- n& O! M
6 t. h9 I* ~8 N+ C9 G
When to Use Recursion 9 t/ J5 v) O+ {7 G# K. I& R3 l0 D - ~, e, U3 q" y8 A" X Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). 5 @- Z T# j4 A: T) [" L& o3 n$ \7 I5 G( S
Problems with a clear base case and recursive case.0 P: m9 g1 q% E; z* F
: C. {" f8 l y, fExample: Fibonacci Sequence- { W! C; @8 O
0 e7 D+ ^8 a: j* y" i- }- a' QThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: - p0 N( l4 a( q% R! y 6 t; H7 Q* Y7 _( @% R3 L' B Base case: fib(0) = 0, fib(1) = 1+ o( E0 ]+ ~5 }2 `4 l$ Y* Q
9 H5 M3 E! Y# }. ?3 X j; \3 l Recursive case: fib(n) = fib(n-1) + fib(n-2)' w+ l W7 `% q
H- {1 V* W, H
python 9 l5 E& L* R% p8 ~1 L" g, f* B9 p8 [ r _1 _
% z& \$ ?; ], Z* H% i3 x2 i: h! i. `) Vdef fibonacci(n):* w2 d! I: m& L
# Base cases % L, o+ ~# |. L; b4 J: R" u if n == 0: ( V2 }6 W6 Q ~: H6 z& z7 V return 0 + n# j% o3 h1 k, M y4 R elif n == 1: / Z O" l" e L( f return 1 * D/ T p- v0 }$ P# S # Recursive case7 M: d3 P0 P. W/ j: t& U6 Y
else:2 ]. h; X( ]; ?0 l& d- H
return fibonacci(n - 1) + fibonacci(n - 2) 6 j6 T% c3 X0 G% s, {; E. Z: t4 y* V2 g
# Example usage8 h0 p0 N% S4 M. l2 ^/ G' A5 I
print(fibonacci(6)) # Output: 8 ( Q9 o U% }/ ^$ \; y1 H# ? $ P* @" N& i# }2 h) z9 F4 P K) dTail Recursion, l& n1 T6 l W) X
7 v3 M4 @' M+ c
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).9 Z% F- w! x. p' u% C5 P& P
: u- E; \9 j* u$ P. X2 l+ e0 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 现在的开发流程,让一个老同志复习复习,快忘光了。