' T7 ]) c0 m7 P$ v3 z9 b+ J递归是一种通过将问题分解为更小的同类子问题来解决问题的方法。它的核心思想是:**函数直接或间接地调用自身**,直到满足终止条件。 ; j& u: [" M8 U% P+ R 9 n; Y1 O& a+ M9 i, p9 d 关键要素. E+ [. I1 i) i7 V' x i& g! |
1. **基线条件(Base Case)**8 a' o1 ^8 ?1 s# e7 p; I
- 递归终止的条件,防止无限循环 ) l) s2 W; w' ^5 b/ J. Q - 例如:计算阶乘时 n == 0 或 n == 1 时返回 1, Q+ t* q$ R! {5 f! `4 v4 s
" w2 Q; _, W8 k, t' U2. **递归条件(Recursive Case)** # a' a$ K8 ^. b# W' o8 |% O - 将原问题分解为更小的子问题 # p5 A% A6 S2 ?: t6 b: Y0 f( M - 例如:n! = n × (n-1)!0 v1 R% C5 {' n x3 m A7 g7 r
; x- n$ B+ Y e+ z& T
经典示例:计算阶乘" I M5 o2 Q$ m9 l4 E5 [$ ]% |3 J# q
python + j* a8 |1 b }% f fdef factorial(n): 9 j9 B6 c" m( L- O# v if n == 0: # 基线条件: N. j0 M: f; s- B' A7 m
return 10 r8 h; C0 X n
else: # 递归条件 - A/ X# d1 \3 k& Q+ P0 V return n * factorial(n-1)" E. A. [# V7 o) ]6 D
执行过程(以计算 3! 为例):7 @# A m% P/ \3 ?) k8 l
factorial(3)' ^" D1 k5 k0 ]3 m0 Y
3 * factorial(2)+ p! F' V' H' {: b" q% u9 F0 a
3 * (2 * factorial(1)) 9 J- S4 E2 n( |! X3 * (2 * (1 * factorial(0)))5 l6 l9 }4 a0 N$ f& @" m
3 * (2 * (1 * 1)) = 6 {5 P9 a" w& R4 k( ^, j ! i$ D' W* `! S, g2 u# e 递归思维要点& v1 V# m7 h& a6 T* d
1. **信任递归**:假设子问题已经解决,专注当前层逻辑7 i Z y. ?/ M6 t8 b3 C
2. **栈结构**:每次调用都会创建新的栈帧(内存空间) ' \, U+ x" m& d2 ?) A+ f3. **递推过程**:不断向下分解问题(递) ' V [2 t2 b u+ J( Z1 g" O4. **回溯过程**:组合子问题结果返回(归) . F! A2 K$ I/ P8 G# A/ o2 [0 m6 Y/ }
注意事项9 M6 b) }; a) `; B
必须要有终止条件" n% l0 u0 ]& g) N& o" w# z
递归深度过大可能导致栈溢出(Python默认递归深度约1000层) a+ C+ e" a$ r$ T* v. J9 W8 `某些问题用递归更直观(如树遍历),但效率可能不如迭代' i( F* H5 A; f& s% e$ B+ S
尾递归优化可以提升效率(但Python不支持)9 g& e6 b4 j4 i9 A, q, L
+ q! }- n8 b1 c% w ~ 递归 vs 迭代 & _: E- I% O1 X8 L) G| | 递归 | 迭代 | . _# z+ q# L' i% g) f|----------|-----------------------------|------------------| 2 x; R8 h1 e7 s: m; n| 实现方式 | 函数自调用 | 循环结构 |' g) W5 J4 ^3 Z: D! d- s1 R/ {
| 内存消耗 | 需要维护调用栈(可能溢出) | 通常更节省内存 | " ^, b/ E' B5 U| 代码可读性 | 对符合递归思维的问题更直观 | 线性流程更直接 | & q+ }2 b7 H" B2 l2 ^: R4 h) c9 B) ]| 适用场景 | 树结构、分治算法、回溯问题等 | 简单重复操作 |, Y1 K- U F0 _6 o. f
/ O- r, o4 O0 C6 P6 _
经典递归应用场景' D% d& w; i. F* s4 O4 k2 \7 D
1. 文件系统遍历(目录树结构), I. C0 |1 S; ~& f" a2 B
2. 快速排序/归并排序算法 1 {9 Y% c! I3 f3. 汉诺塔问题 / L6 p" C( d/ E2 W* B4. 二叉树遍历(前序/中序/后序) 0 }% H5 f% P1 H" ]5. 生成所有可能的组合(回溯算法) 3 S( E6 G) w( v# l% A( I ?# L+ M2 {5 I D& ]) r试着用递归思维想象:你站在一面镜子前,镜子里有无数个逐渐变小的你在照镜子,这就是递归的直观体现。但记住每个"分身"最终都要有结束的时刻,这就是基线条件的重要性。作者: testjhy 时间: 2025-1-30 00:07
挺好,递归思维要点与我能够回忆起来我当时写递归程序的思路很一致,,或者被它唤醒,0 ^& Z" f2 A9 `+ F
我推理机的核心算法应该是二叉树遍历的变种。+ y* R6 L) O0 k) W
另外知识系统的推理机搜索深度(递归深度)并不长,没有超过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: o7 g% {" c2 a9 I4 S
Key Idea of Recursion 7 H. t- r8 p2 c1 Y9 S " e/ k! V+ N. xA recursive function solves a problem by: ' R; N% r+ v4 o0 E5 S7 A4 M. R + u3 q6 c; K& G K3 T9 X5 l2 ]# c Breaking the problem into smaller instances of the same problem. * ?6 O9 H& a! X7 O1 I 9 A4 k$ D, Y+ f3 U. F: ^$ T" R Solving the smallest instance directly (base case).& R( @. H( s( v, z1 |
6 O9 p( j y" y S
Combining the results of smaller instances to solve the larger problem. h; g7 ~$ m' K4 d, V7 Y6 ? # E7 J' }! c2 \+ N* V% R/ ZComponents of a Recursive Function8 M, t6 v5 N* i* P
7 z+ o2 U* R% K1 q
Base Case:' D2 W- e. `* e+ p0 N5 d. x) P$ [
! _% l( d8 m2 h* B This is the simplest, smallest instance of the problem that can be solved directly without further recursion.5 n6 Z( Z. P. u5 o# v( E: p; H+ Y
/ ]" T. g2 |9 G" P It acts as the stopping condition to prevent infinite recursion.6 d4 o( y( z! V" O! N9 A
, s, \ F& C5 l$ F! V; }& P
Example: In calculating the factorial of a number, the base case is factorial(0) = 1. / T% Z. ]+ S6 i9 a4 x1 w4 s0 R2 p
Recursive Case:- d& t" C4 x/ c2 q
" v$ v/ L+ |+ J& d8 L5 l* T2 e
This is where the function calls itself with a smaller or simpler version of the problem. $ t2 s" a3 E. p 0 D4 e# {! c( R Example: For factorial, the recursive case is factorial(n) = n * factorial(n-1).5 |( w, f( B5 P
* t4 v4 ~6 V$ R& Q. yExample: Factorial Calculation 5 u. W3 B, ]; _* n$ e 7 s/ t* X% g0 o! g" T' m9 oThe 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: `- d% n% Y2 k! ]$ {0 ]2 l : R2 ^3 Z" C/ d Base case: 0! = 1 / C, i4 o. \4 D! j8 f2 v- ^+ t( B& M( B r) D8 \" C) D8 F5 [7 C
Recursive case: n! = n * (n-1)! + B/ S; M1 ?8 Z + S& Q& b8 ~/ {0 x7 \9 L% MHere’s how it looks in code (Python): + f( Z0 a: c% M0 s/ Wpython2 }+ n( Y" J R, M' F( N4 r
+ d% }+ j5 R" z, G* K! |
/ f$ G$ \. x, @3 L
def factorial(n):- N ]- ^; L- o6 R" C! ]" [3 [
# Base case2 k' q8 L6 n( `( d1 l
if n == 0:) Z d2 r; ^% _$ |8 Z6 X; d
return 1 , D4 @" R) H( q! _3 U # Recursive case2 N7 Y/ \. E; M) f
else:+ ~, a+ k0 Z5 `! C* L
return n * factorial(n - 1)3 {5 \) n6 P' h0 G0 |- L P* B7 ]
2 e6 Z/ U W% o! G& ]" O4 w# Example usage % p/ n2 d7 V+ l, }- h" fprint(factorial(5)) # Output: 120+ l6 p/ _# Q1 p. m- B* o
( V' m: l4 {9 R# o1 kHow Recursion Works6 X) j5 a% v2 f& v m
1 F: }- i# A/ w7 w% x4 m$ y6 e The function keeps calling itself with smaller inputs until it reaches the base case. & l' t( ^9 l. C- F9 Q( y q& V) v3 A! E2 U
Once the base case is reached, the function starts returning values back up the call stack.- Q( Q1 V2 X5 o v
: _5 M$ R8 z% v- k5 e These returned values are combined to produce the final result.0 K" n$ U& U8 D$ n2 Z- y
9 r0 e# m: @5 r4 a2 Q! k! gAdvantages of Recursion ) y5 k4 @( U& D" }6 U 3 V/ T p# n' \0 j9 |$ R' Q7 s 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).8 h* w+ p! p3 J, \1 b( u8 A5 u
4 J+ C0 ]6 ~! P7 n# {: s$ [* \
Readability: Recursive code can be more readable and concise compared to iterative solutions. - f/ J: ?, @/ z- i( w% Q( t 1 m' d2 e- u/ Q# m( r! YDisadvantages of Recursion0 C7 h/ v0 y; h- Z. [ Q3 B
2 t, e+ _$ n) |2 M
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. ) L1 J0 V3 m: b8 ^5 j 6 w/ C1 H' H; b: d4 ~% r4 ^ Inefficiency: Some problems can be solved more efficiently using iteration (e.g., Fibonacci sequence without memoization).; {& E% V$ o C7 _$ I
; E( X6 x, q/ y3 n( q8 M( ] d. ~
When to Use Recursion 9 T, q% h, w& z$ C7 K, e. q+ S% m" m3 q1 Q( G
Problems that can be broken down into smaller, similar subproblems (e.g., tree traversals, sorting algorithms like quicksort and mergesort).) C- ^) A3 |/ [. N' q
5 {9 p1 Y7 W; B; ~) G: R8 F) y Problems with a clear base case and recursive case.0 T+ l( b+ o* `8 S. s
) f. ~% A6 l0 D% Z" Y g! ?Example: Fibonacci Sequence. ?% q& h2 A9 ]9 O& l3 R7 O
" S4 L: l" G3 X* B$ e1 NThe Fibonacci sequence is another classic example of recursion. Each number is the sum of the two preceding ones:+ ?" a7 v5 Y1 X) w: r% Q
( K" u* W% m* Q u R* V& j4 ]
Base case: fib(0) = 0, fib(1) = 16 n& w* Z0 ~& ~" `) p r6 }- n
8 ^; l* I! E3 C/ s; Z Recursive case: fib(n) = fib(n-1) + fib(n-2) . o0 R+ H; o) h 3 n6 N* D7 p- g0 m, ipython 3 H* r2 C- H+ p' w / v/ B4 K# ~1 _: o $ G" V7 i' K4 d% w1 g, Zdef fibonacci(n): ) b3 L# Y3 n& v+ K5 \6 p5 W* T # Base cases& t7 U4 Z/ e0 |5 [& u
if n == 0: 2 `5 N7 }. N) h; X6 d return 0 # E4 q6 n: r4 D% C# U6 r elif n == 1:2 g8 @" {. i* l8 S) D) m( F5 W; s
return 1 1 A7 K- s$ M+ X: O% t1 e( `$ ^ # Recursive case 5 M8 v" t. G3 e! r9 m4 G: U* K1 [ else: / [ r/ K& H6 A" P/ x% T; X return fibonacci(n - 1) + fibonacci(n - 2)) e0 B3 M' }1 P# u/ q* @! X. ?
$ `! z" |2 H- j+ z" |4 ?8 o# Example usage* o: l/ k- C" x y6 W+ Z' b
print(fibonacci(6)) # Output: 87 L) c3 s. l! A. a7 Z( s
: f. J2 w9 C( [; TTail Recursion- s. y" ?" _' O7 i4 O
, Y* l& T; \% X( q' STail 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). 7 v6 f4 t/ g p! I. n . T+ K( u" F: CIn 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 现在的开发流程,让一个老同志复习复习,快忘光了。