程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 遞歸與迭代

遞歸與迭代

編輯:C++入門知識

      在我接受到的教育中,遞歸似乎是一個很神秘的東西。它難以說清,是高級貨,像一團迷霧。在高中課外學習的過程中,我一開始沒有理解到什麼是遞歸,老師也可能覺得我們比較難以理解,所以後來就沒有統一說說。而我也覺得貌似挺難的,也貌似不用也可以,所以就沒了回事。後來到了大學,教編程語言的老師居然極度忽視遞歸,那時的我已經知道遞歸的重要性,她竟然說了些站不住腳的觀點就糊弄過去,說白了,很多都是語法糖衣。

 


        直到看sicp的時候,我或許才真正感受到遞歸。

 


        首先說明一下,sicp的展開基於一種lisp的方言——scheme語言,它沒有所謂的循環語句,因此從語法形式上看,所有的重復做某事的過程都是遞歸過程。那麼按照一般思維,它是否就不存在迭代呢?因為在很多命令式語言諸如C,java等都具有循環語句,所以我們一般寫迭代都是用循環語句來寫,而不會用函數遞歸來寫,這是比較容易混淆的一點。在scheme語言中,將這種基於具體計算過程的分類,分為遞歸計算過程和迭代計算過程。我們很多時候都基於語法形式而忽略計算模式來說,其實是不太准確的。

(下面是sicp中文版關於此的一段引文:

       當我們說一個過程是遞歸的時候,論述的是一個語法形式上的事實,說明這個過程的定義中(直接或者間接地)引用了該過程本身。在說某一計算過程具有某種模式時(例如,線性遞歸),我們說的是這一計算過程的進展方式,而不是相應過程書寫上的語法形式。)

 


      一般來說,遞歸計算過程呈現一種先擴展後收縮的計算模式,即需要解釋器(或編譯器)維護著某些信息,並會隨著擴展而增加。而迭代計算過程並沒有任何擴展或收縮,它只需要幾個固定的必要的信息。用階乘函數可以很簡潔地闡釋:

;遞歸計算過程 
 

(define (factorial n) 
  (if (= n 1) 
      1 
      (* (factorial (- n 1)) n))) 
 
;迭代計算過程 
(define (fact-iter counter result) 
    (if (= counter 1) 
        result 
        (fact-iter (- counter 1) (* counter result)))) 
(define (factorial1 n) 
  (fact-iter n 1)) 

;遞歸計算過程
(define (factorial n)
  (if (= n 1)
      1
      (* (factorial (- n 1)) n)))

;迭代計算過程
(define (fact-iter counter result)
    (if (= counter 1)
        result
        (fact-iter (- counter 1) (* counter result))))
(define (factorial1 n)
  (fact-iter n 1))

 


        當然,遞歸計算過程還可以簡單分為線性遞歸計算過程(階乘)和樹形遞歸計算過程(斐波拉契)。顯然,樹形遞歸存在大量的冗余計算,但其特點是簡潔。

 


        暫時先說這麼多,下一篇分別舉幾個例子來說明遞歸計算過程和迭代計算過程。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved