+ u" \1 b. E% v1 ]$ t, l5 Y# q递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 ) d2 I, V2 G6 m" W: U : n2 _ t: j6 R% x/ d* Y# ` 关键要素% [$ s2 Q* y% ]! E0 ?
1. **基线条件(Base Case)**4 \, b0 W# _) T/ c2 H W" b
- 递归终止的条件,防止无限循环+ g1 K! ?: `& g0 Q# j* W
- 例如:计算阶乘时 n == 0 或 n == 1 时返回 1 5 |# ]% e7 T6 ~ O, m* r! T) z* ]" |
2. **递归条件(Recursive Case)**! M# r# L6 z& }, X: R
- 将原问题分解为更小的子问题* ]( P4 z+ G2 l+ w" u/ k5 @' {
- 例如:n! = n × (n-1)! " Z3 \ p E, ?" W8 q7 h! z 5 E" v8 f% _+ }- N" n! t 经典示例:计算阶乘 2 s4 h% ~2 a9 n# E0 H# Z) Q wpython 1 H' |5 ]& g2 k" _) gdef factorial(n):' l$ l5 }: r& i
if n == 0: # 基线条件, O# V9 g) Y# Q+ m; Y
return 1 ! \9 r+ n8 Y u else: # 递归条件# M* h g+ M( k& R; E4 g8 U; k
return n * factorial(n-1) 7 S: b# c$ F+ `/ @; X5 Q执行过程(以计算 3! 为例):" Y$ l/ V: f+ i: T: r
factorial(3): q a2 G# _' |/ W
3 * factorial(2) % |( Y3 q. F2 G- I3 * (2 * factorial(1)) p7 |0 u( T3 T3 * (2 * (1 * factorial(0))) ) B3 ] H. u5 K( t3 * (2 * (1 * 1)) = 66 H9 J! i: s, ^. F& e6 A( N
; F8 W5 z6 S* |& I- s7 ^' ~
递归思维要点 6 Q; p7 ], W3 i( I% K- k0 v8 r1. **信任递归**:假设子问题已经解决,专注当前层逻辑1 G2 R# h6 p# q! c" H* _8 j
2. **栈结构**:每次调用都会创建新的栈帧(内存空间) - B. B' J4 ^$ C+ J, _$ J. N3. **递推过程**:不断向下分解问题(递)& f5 ^# Z9 s1 ?" s9 O0 r* b
4. **回溯过程**:组合子问题结果返回(归)) y Y. q; V' _4 P& w! N6 O0 F
+ n. K2 P) s( G% R% Q, `% S
注意事项 ( F7 @! s( N! }, `! J, Z/ D6 l必须要有终止条件6 q- M, \/ Q9 {+ `1 l# C
递归深度过大可能导致栈溢出(Python默认递归深度约1000层)4 _/ p0 j$ Z3 v4 o$ u9 [
某些问题用递归更直观(如树遍历),但效率可能不如迭代" ~, R% T9 B8 O/ a) [: B
尾递归优化可以提升效率(但Python不支持)8 \! P2 x2 J n7 ?" I/ b3 K( ~
4 q, {/ A5 `, c
递归 vs 迭代 6 v. o: Y- x4 J$ O6 e2 P| | 递归 | 迭代 | 1 r6 E5 @, t4 |- w* m9 v" _|----------|-----------------------------|------------------| ( h6 E: B% ]% Z( k5 a| 实现方式 | 函数自调用 | 循环结构 | ( _: O/ T: J% q! X: \8 d| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | ! }# a+ Z$ \* ]! ]# l8 b/ x| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 |+ x& ?5 E. |1 k! C* x! ?) z z
| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |5 ^3 c, U4 t4 Z& x
# O1 B: L/ e& o& f
经典递归应用场景 + [8 i$ X" \9 G7 Y+ `1. 文件系统遍历(目录树结构) ( E! Y; D2 J( x* z, m" e! r2. 快速排序/归并排序算法 9 z6 M0 O$ g7 N |/ J3. 汉诺塔问题 ! ~& W3 i5 W9 g4 s. e4. 二叉树遍历(前序/中序/后序) : E9 U! U1 F, n/ h9 d: e( Q5. 生成所有可能的组合(回溯算法) 7 P2 l! T8 r# Z# ]/ l0 T& y 6 B9 ~7 |! c" s+ G试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,- i# P/ W& i- W* M! c! H6 R! B3 l2 }
我推理机的核心算法应该是二叉树遍历的变种。 4 ]+ p1 Q8 l+ f" p: V8 }1 F另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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:, Q2 b) O* e, i
Key Idea of Recursion0 K: ?) a( @& R; w9 F
: P# Y* z, B/ r0 o
A recursive function solves a problem by: 9 {% m/ g j2 ^: B 6 U# J- N0 ^% u% \+ x Breaking the problem into smaller instances of the same problem.& v. t6 a4 }/ `& Q) V
+ [- L |. X0 R% s2 N( V: K8 e Solving the smallest instance directly (base case).2 Z9 J0 [8 T& `5 z. V- f
' K4 q' ]/ J% _. s
Combining the results of smaller instances to solve the larger problem. " Z; J* N6 K7 y7 l0 n" u! `/ m# V i. Q" q& i2 M
Components of a Recursive Function ! x6 k0 [" p+ H. v# N( ~5 ~" X . D- u o5 E7 E( z$ W; {4 O* R Base Case:) x) g; I) |7 j5 C W9 H/ n$ k
! [0 J7 Q& b9 g) m This is the simplest, smallest instance of the problem that can be solved directly without further recursion.$ s; e+ x0 G3 w4 P) `
7 l. O1 a, ]# J+ w. H* N It acts as the stopping condition to prevent infinite recursion.. u7 Y& ?$ D: j$ B
/ n' w7 X0 t) H2 O3 @7 R
Example: In calculating the factorial of a number, the base case is factorial(0) = 1.+ t: A+ D/ k/ Y2 x9 h
& N& [8 [/ X; L G+ ^' Q) D* x/ ~$ N Recursive Case: 4 q# ~! d1 ?. D5 C) q& s* l' d+ [9 K
This is where the function calls itself with a smaller or simpler version of the problem. W& V1 ]& @- U! i2 ~3 L9 L. _
3 Z7 J, T% F. h: U- h' i( s
Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1). / U D# H7 ^7 Z; [' T ! L! X0 e# [ l" J: ~Example: Factorial Calculation 3 }9 Y# u5 |( \" g! M - p$ ~+ X) l, 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:0 G+ f) n6 Q8 U) [# `1 }
! r8 W% d/ n$ N6 O
Base case: 0! = 1 . y% _' n" z9 E: v7 G: z5 u7 `, n2 |1 D# g/ T! R
Recursive case: n! = n * (n-1)! 3 d4 M0 \9 ?9 D D- [ 1 s9 C0 F7 U8 h% Z1 k, h4 zHere’s how it looks in code (Python): ' j) p2 D. c4 L u ypython- G- V% ^$ j6 S
: s( N$ m: ~" l! ^
) X) h& I( T3 R5 }& @+ } wdef factorial(n):" i/ z, S$ ~8 {/ q" r1 V* [ ^
# Base case) p+ _) J( @% u. `4 _7 u5 j f* q
if n == 0: ! T1 `, b1 x2 N1 e' T return 1 * l$ Q4 O1 B1 U3 b6 m3 e2 p4 y # Recursive case" R: ]) Q( H+ F2 C- X. [7 B6 P
else: 8 t" d1 w4 w: \3 B9 I# a& t* h4 C return n * factorial(n - 1) 9 R# n) u% B* L+ k g8 z- k( r. o3 n* T& d, l* K# Example usage 0 P; I& y3 J u4 |( n! I) Fprint(factorial(5)) # Output: 1202 \) l3 E; A/ S# u( w5 b
' R5 i( R2 c ], g! L
How Recursion Works ! y) H: L4 D# K, D6 Z1 P$ Y' e4 Z8 a 9 ?3 j i' Q4 Y( m The function keeps calling itself with smaller inputs until it reaches the base case.) z. r# q; L* _
9 y: ?8 j# R4 j( q3 | Once the base case is reached, the function starts returning values back up the call stack." ]. m& n$ Z8 U. |# ? l
) S$ a- ^% v% @8 a) a These returned values are combined to produce the final result.% l: f+ N+ B6 B/ N- _
3 b- B. ]- w; c) R2 ]" {' a
For factorial(5): - n4 J6 o7 X% v' {! @) g% D" f A0 q% R
4 f" \" g/ P3 E2 J7 _# ]0 |8 _Then, the results are combined: - c( L" F$ O: A1 f" c1 X" h* Z4 S2 ]. D1 Z
/ e7 R0 n$ \. lfactorial(1) = 1 * 1 = 1 & K, T8 o2 h0 O+ Cfactorial(2) = 2 * 1 = 2+ g, D1 a2 ~4 [4 [ L' P+ y8 n
factorial(3) = 3 * 2 = 6$ W: e. J6 n" S( G7 w Y
factorial(4) = 4 * 6 = 247 R" R7 M9 p( U l% ?. v
factorial(5) = 5 * 24 = 120 + G S! D4 S* d" l1 ^- f k u% j y. P% L6 Q* n9 Y( fAdvantages of Recursion 3 r. `9 d0 a+ o, q; i9 U" m4 r$ l. y' I4 z+ C
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). p+ O6 w4 ~ G' l, a2 z$ y
7 M8 x' h3 }4 n1 e. Y0 o/ p+ w
Readability: Recursive code can be more readable and concise compared to iterative solutions. ) `' n+ `: X2 m% ^- C2 k( P- x - y; ]# u+ m" X) S2 T- M; b; o- UDisadvantages of Recursion ) j% O! Z: C9 B( }4 @& v. N7 L) f/ 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." p9 G+ T/ r% J$ }' z7 r
0 D! m& x' W5 n: {9 `6 ~! U, z
Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization). 2 Y' i `3 S, A2 U7 g4 M( k- A" t6 r- p' s+ v
When to Use Recursion $ w' ?7 G1 j. b* ?) a) [" a- k0 Q: j" |4 i+ b3 d0 J
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort). ' G2 u& G) f! ], B3 V) c 4 h5 q) @1 p& P7 Y$ a' P Problems with a clear base case and recursive case.+ w& g7 T' |# ?7 d6 g
/ ^9 e. T; L2 ~
Example: Fibonacci Sequence . E7 [! f# N, F' @ 0 U8 S. P" p7 S; O; D# IThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones: 2 w( X/ ?; k% E% H0 Z2 h3 u5 _6 v1 m& c
Base case: fib(0) = 0, fib(1) = 1/ ]# c' T7 F W2 }( K8 y# d4 ~
; B$ ^' C7 Z7 i8 E Recursive case: fib(n) = fib(n-1) + fib(n-2)8 H! w& O+ b7 }. A, z- s9 s
3 c* t. }/ \' h. ~. l$ h
python 4 J0 A: W4 r I( M' u& K1 m7 E0 K6 ~* o/ c G# ^4 R
( @: ^) r) ]# O" F/ e7 w+ L9 d q
def fibonacci(n):# A* `- ~6 h9 i( z6 B' l
# Base cases7 D" P( C2 x3 o* S8 z# x/ k/ C
if n == 0: ! {5 u" b) f* `, K5 t/ l3 p return 0 ( B* S8 ^/ T# [" s8 z! Z* _2 r2 F/ U elif n == 1:; T1 v: [* D- d; ?$ j+ ~) k
return 1 + F: r1 \/ v- B) T # Recursive case , t1 Z. F/ g- V5 S else:) O: m3 O( B1 q
return fibonacci(n - 1) + fibonacci(n - 2) " _& A+ i E" ~: w5 a% u5 B7 I% E# x% v) A# g' e+ ?) X1 e
# Example usage 2 R D% L3 k+ P% Y0 c/ S! X5 O; K2 a' h) Vprint(fibonacci(6)) # Output: 8 & j5 D# m! z% U# R# j3 {/ S" P h' B6 `! g
Tail Recursion/ i8 U4 b4 |7 C0 P$ ] \, g
2 ?. ^; G% x: ]) q" J! Z6 J
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). ( ?8 U# Q# E! H4 w3 H0 ] % D" N, n7 B: z8 tIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。