字串 `"hello"` 在記憶體中:`h e l l o \0`
遞迴遞進:`foo("hello")` → `foo("ello")` → `foo("llo")` → `foo("lo")` → `foo("o")` → `foo("")` (基底返回)
遞歸歸出:印 `o` → 印 `l` → 印 `l` → 印 `e` → 印 `h` → **完成反轉**
#include
/**
* 遞迴反轉輸出字串
* @param s 字串指標 (遞迴中不斷後移)
*/
void reversePrint(const char *s) {
// 基底情況:字串結束符
if (*s == '\0') {
return; // 到達末端,開始回溯
}
// 遞迴處理下一字元 (遞進階段)
reversePrint(s + 1);
// 回溯階段:輸出當前字元
putchar(*s); // 等同 printf("%c", *s),效率更高
}
int main() {
char str[] = "hello world";
printf("原始: %s\n", str);
printf("反轉: ");
reversePrint(str);
printf("\n");
return 0;
}
呼叫堆疊 (遞進) 返回輸出 (歸出) ┌─────────────────────┐ ┌─────────────────────┐ │ reversePrint("hello world") │ ← 最後返回 │ (無輸出) │ │ reversePrint("ello world") │ │ putchar('d') → 'd' │ │ reversePrint("llo world") │ │ putchar('l') → 'l' │ │ reversePrint("lo world") │ │ putchar('r') → 'r' │ │ reversePrint("o world") │ │ putchar('o') → 'o' │ │ reversePrint(" world") │ │ putchar(' ') → ' ' │ │ reversePrint("world") │ │ putchar('d') → 'd' │ │ reversePrint("orld") │ │ putchar('l') → 'l' │ │ reversePrint("rld") │ │ putchar('r') → 'r' │ │ reversePrint("ld") │ │ putchar('o') → 'o' │ │ reversePrint("d") │ │ putchar('w') → 'w' │ │ reversePrint("") │ ── 基底 ── │ (返回) │ └─────────────────────┘ └─────────────────────┘ 最終輸出: "dlrow olleh"
原始: hello world
反轉: dlrow olleh
| 概念 | 說明 |
|---|---|
| 遞進階段 | 不斷 `s+1` 移動指標,**不輸出**,直到 `\0` |
| 歸出階段 | 函數返回時,**依序輸出** 當前 `*s`,形成反序 |
| 堆疊隱式儲存 | 每層遞迴在堆疊保存 `s` 指標值,返回時自動還原 |
| 尾遞迴? | **非尾遞迴** (遞迴呼叫後還有 `putchar`),無法編譯器優化,堆疊深度 = 字串長度 |
| 空間複雜度 | O(n) 堆疊深度,長字串 (超過 ~10⁵) 會堆疊溢位 |