1. 程式人生 > >漫談遞迴:遞迴的思想 用歸納法來理解遞迴

漫談遞迴:遞迴的思想 用歸納法來理解遞迴

為什麼要用遞迴

程式設計裡面估計最讓人摸不著頭腦的基本演算法就是遞迴了。很多時候我們看明白一個複雜的遞迴都有點費時間,尤其對模型所描述的問題概念不清的時候,想要自己設計一個遞迴那麼就更是有難度了。

很多不理解遞迴的人(今天在csdn裡面看到一個初學者的留言),總認為遞迴完全沒必要,用迴圈就可以實現,其實這是一種很膚淺的理解。因為遞迴之所以在程式中能風靡並不是因為他的迴圈,大家都知道遞迴分兩步,遞和歸,那麼可以知道遞迴對於空間效能來說,簡直就是造孽,這對於追求時空完美的人來說,簡直無法接接受,如果遞迴僅僅是迴圈,估計現在我們就看不到遞迴了。遞迴之所以現在還存在是因為遞迴可以產生無限迴圈體,也就是說有可能產生100層也可能10000層for迴圈。例如對於一個字串進行全排列,字串長度不定,那麼如果你用迴圈來實現,你會發現你根本寫不出來,這個時候就要呼叫遞迴,而且在遞迴模型裡面還可以使用分支遞迴,例如for迴圈與遞迴巢狀,或者這節列舉幾個遞迴步進表示式,每一個形成一個遞迴。

用歸納法來理解遞迴

數學都不差的我們,第一反應就是遞迴在數學上的模型是什麼。畢竟我們對於問題進行數學建模比起程式碼建模拿手多了。 (當然如果對於問題很清楚的人也可以直接簡歷遞迴模型了,運用數模做中介的是針對對於那些問題還不是很清楚的人)

自己觀察遞迴,我們會發現,遞迴的數學模型其實就是歸納法,這個在高中的數列裡面是最常用的了。回憶一下歸納法。

歸納法適用於想解決一個問題轉化為解決他的子問題,而他的子問題又變成子問題的子問題,而且我們發現這些問題其實都是一個模型,也就是說存在相同的邏輯歸納處理項。當然有一個是例外的,也就是遞迴結束的哪一個處理方法不適用於我們的歸納處理項,當然也不能適用,否則我們就無窮遞迴了。這裡又引出了一個歸納終結點以及直接求解的表示式。如果運用列表來形容歸納法就是:

  • 步進表示式:問題蛻變成子問題的表示式
  • 結束條件:什麼時候可以不再是用步進表示式
  • 直接求解表示式:在結束條件下能夠直接計算返回值的表示式
  • 邏輯歸納項:適用於一切非適用於結束條件的子問題的處理,當然上面的步進表示式其實就是包含在這裡面了。

這樣其實就結束了,遞迴也就出來了。遞迴演算法的一般形式:

01 void func( mode)
02 {
03 if(endCondition)
04 {
05
constExpression         //基本項
06 }
07 else
08 {
09 accumrateExpreesion     //歸納項
10 mode=expression         //步進表示式
11 func(mode)          //呼叫本身,遞迴
12 }
13 }

最典型的就是N!演算法,這個最具有說服力。理解了遞迴的思想以及使用場景,基本就能自己設計了,當然要想和其他演算法結合起來使用,還需要不斷實踐與總結了。

相關推薦

漫談思想 歸納法理解

為什麼要用遞迴 程式設計裡面估計最讓人摸不著頭腦的基本演算法就是遞迴了。很多時候我們看明白一個複雜的遞迴都有點費時間,尤其對模型所描述的問題概念不清的時候,想要自己設計一個遞迴那麼就更是有難度了。 很多不理解遞迴的人(今天在csdn裡面看到一個初學者的留言),總認為遞迴完全沒必要,用迴圈就

從“數學歸納法”到理解演算法”!

每章一點正能量:人的一生可能燃燒也可能腐朽。 前言 相信大家在面試或者工作中偶爾會遇到遞迴演算法的提問或者程式設計,我們今天來聊一聊從數學歸納法到理解遞迴演算法。如有錯誤還請大家及時指出~ 本文已同步至 GitHub/Gitee/公眾號,感興趣的同學幫忙點波關注~ 1. 數學歸納法 1.1 簡

漫談迴圈與迭代

漫談遞迴:迴圈與迭代  理清遞迴、迭代、迴圈的概念 感謝  參考或原文   先摘抄“為之漫筆”對這幾個概念的一段理解: loop、iterate、traversal和recursion這幾個詞是計算機技術書中經常會出現的幾個詞彙。眾

劍指offer面試題求二叉樹的映象(、迴圈解法及測試例)

題目:給定二叉樹,將其變換為源二叉樹的映象。 二叉樹的定義如下: struct TreeNode {     int val;     TreeNode* left;     TreeNode* right; }; 輸入描述: 二叉樹的映象定義:     源二叉樹    

資料結構練習之實現5的階乘#C語言實現

剛學資料結構,給大家分享一下今天學習資料結構的棧中的一個練習 也算是順便記錄一下學習過程 #include <stdio.h> typedef struct StackNode { int vn; //儲存n的值 int vf; //儲存fun(n)的值 int t

day 17homework 三級選單

menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '網易': {}, 'google': {}

表儲存代替演算法

我們知道遞迴演算法非常低效,低效的原因在於遞迴的過程會產生冗餘計算。 拿我們熟悉的斐波那契數列為例,計算公式為:F(n) = F(n - 1) + F(n - 2),其中F(0) = F(1) = 1。 例如計算F(5)的執行過程: 在此過程中,F(4) 執行了1次;F(3)執行了2次;F(2)執行

圖解漢諾塔,Python實現經典

感謝漂流的雲的圖解漢諾塔問題(遞迴求解) (1)先從最簡單的模型開始,假如A柱有2個盤,我們的任務是把這兩個盤按照規則(小疊在大上)移到C柱。操作步驟如下所示: (2)現在把原始時A柱盤子數增加到100,那步驟不言而喻變得很複雜,但是我們可以通過一種方法把複雜的問題簡單化: 可能此時你會

《零基礎入門學習Python》(23)--這幫小兔崽子

前言 我們接下來吧遞迴的用法再熟練一點,大家都知道斐波那契數列吧,以下我們以實際的兔子繁殖的例子來編寫一個關於斐波那契數列的遞迴函式 知識點 我們都知道兔子繁殖能力是驚人的,如下圖:  我們可以用數學函式來定義:  迭代實現 def

《零基礎入門學習Python》(24)--漢諾塔

前言 這節課主要講解用遞迴的方法,實現漢諾塔的解答  知識點 這節課主要講解用遞迴的方法,實現漢諾塔的解答  對於遊戲的玩法,我們可以簡單分解為三個步驟: 1) 將前63個盤子從X移動到Y上。  2) 將最底下的第64個盤子從X移動

深入理解思想

1、什麼是遞迴 本質上,將原來的問題轉換為更小的同一問題。問題規模可以不斷縮小,直到達到一個不能再縮小的基本問題,解決這個基本問題,就解決了整個問題。 例如,使用遞迴思想對自然數1、2、3…n-1 、n求和: sum(n) = n +sum(n-1); //sum(n-1)就是被

第023、024講這幫小兔崽子、漢諾塔

目錄 動動手 0. 使用遞迴編寫一個十進位制轉換為二進位制的函式(要求採用“取2取餘”的方式,結果與呼叫bin()一樣返回字串形式)。 1. 寫一個函式get_digits(n),將引數n分解出每個位的數字並按順序存放到列表中。 2. 還記得求迴文字串那道題嗎?現在讓你使用遞迴的方式

全排列(實力蒙)

#include <iostream> using namespace std; void swap(int &a,int &b) {  int temp=a;   a=b;   b=temp; } void pai_xu(int a[]

逆波蘭表示式

1.問題 逆波蘭表示式的定義: 一個數是一個逆波蘭表示式,值為該數; “運算子 逆波蘭表示式 逆波蘭表示式” 是逆波蘭表示式,值為兩個逆波蘭表示式的值運算結果 樣例輸入: * + 11.0 12.0 + 24.0 35.0 樣例輸出: 1357.000000 提示:

N皇后問題

1.問題 在國際象棋中,皇后的移動方式為橫豎交叉的,因此在任意一個皇后所在位置的水平、豎直、以及45度斜線上都不能出現皇后的棋子,例子 2.思路 每個皇后必須放在不同行、不同列上、不同斜線上 3.程式碼 #include <iostream> #include

漢諾塔問題

1.題目 2.思路     1、把A上面n-1個盤子移動到B上。    2、把A上最後一個移動到C;    3、把B上n-1個移動到A上,再把B上最後一個移動到C; 如此

結算系統時候到的左側 導航條功能

<template> <el-scrollbar wrapClass="scrollbar-wrapper"> <el-menu mode="vertical" :show-timeout="200" :default-act

javascript分別for迴圈和計算不死神兔

function getSum(n) {   var n1 = 1;  //初始化兩個月的兔子個數   var n2 = 1;   var sum = 1;  //定義一個累加和 ,如果傳遞的是1或者2,預設值為1   for(var i = 3; i <= n; i++) {   sum =

Java篇WeChat 模仿微信紅包的核心演算法

模仿WeChat的拼手氣紅包 ,例如:10000元傳送50個包。 這50個紅包隨機分配,但是最後相加等於10000. 採用隨機數,隨機紅包金額。 又制定規則,不斷地遞迴運算。 限制最小的紅包金額,例如:0.01,因為考慮人性化,最小的紅包不能是0. 不限制可發出的紅

理解的本質與棧

轉自:https://blog.csdn.net/bobbypollo/article/details/79891556  遞迴的基本思想 所謂遞迴,就是有去有回。 遞迴的基本思想,是把規模較大的一個問題,分解成規模較小的多個子問題去解決,而每一個子問題又可以繼續拆分成多個