999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

循環、迭代與遞歸

2020-04-22 20:36:14方悅
電腦知識與技術 2020年6期

方悅

摘要:該文對比了循環、迭代與遞歸在概念、用法和性質上的異同,以階乘和Fibonacci數列為例在c語言和匯編語言環境中進行說明。

關鍵詞:循環;迭代;遞歸;階乘;斐波那契數列

中圖分類號:TP311 文獻標識碼:A

文章編號:1009-3044(2020)06-0055-03

任何復雜的事物都是由簡單的東西發展演變而來的,讓我們來從頭說起。這里最初始的概念是重復/反復(repeat),意思是一遍又一遍(again and again),是相對于“只做一遍”而言的。從強調“行為次數”到以“執行路徑”為關注點,我們引入了循環。循環(100p)的概念源自對環(cycle)這種物理形狀的邏輯抽象,用于形容運行過程的周而復始。在計算機程序設計中,“循環”這一術語指的是一種專門的控制結構。特征是重復執行循環體中的語句,比一般情況下的順序執行復雜一些,需要跳轉命令和條件判斷組合實現。循環側重于解決問題的過程,至于方法,主要有迭代和遞歸兩種。根據《簡明數學詞典》的定義,迭代(Iteration)指的是重復執行一系列的運算步驟,直到求得最終結果,特點是每一次迭代得到的結果都作為下一次迭代的初始值。在計算機領域,上述“一系列的運算步驟”如果用“子程序”這個詞來代替就容易理解了。在此,迭代是用重復更替的方法,實現了更新變量數值的目的。有別于直接法(或者稱為一次解法),即一次性解決問題。講完了迭代,再來看遞歸。不過在談遞歸之前,引入另外一個詞:遞推。遞推與遞歸,一字之差,卻有不同,我們先看區別。從字面來簡單理解,遞推就是“以此類推”的意思。根據《中國中學教學百科全書·數學卷》定義,遞推是將復雜運算化簡為若干步重復的簡單運算。聽起來有一些抽象。其實遞推本是一個數學概念,源于數列。我們知道,如果數列{an}的第n項依靠其前一項或幾項確定,這種關系就叫遞推。例如:經典的等差數列an=an-1+d、等比數列an=aa-1q、斐波那契數列(Fibonacci Sequence)an=an-1+an-2(n>=3,a1=1,a2=1),等。在計算機科學中,這種由初值求終值的遞推式理所當然用迭代法來實現。

那么什么是遞歸呢?維基百科(Wikipedia)給出了這樣的詮釋:Recursion is the process of repeating items in a self-similarway.意思是說遞歸f或遞推)就是用自相似的方法進行重復。何為“自相似”?根據《數學辭海·第五卷》定義,當該集的任一個局部放大適當倍數后,它的形狀將會和其原來的整體相一致。如何做到這一點呢?在數學與計算機科學中,遞歸通過在函數(子程序)的定義中使用函數(子程序)自身這種方法實現。后面的例子中我們將會看到,遞歸的求解包含“遞推”和“回歸”兩個過程。有趣的是,我們發現遞推和遞歸的英文都是Recursion,二者是不做區分的,都是指用相同的方法進行自我更替。舉個大家熟悉的例子:從前有座山,山里有座廟,廟里有個和尚講故事,講的什么呢?從前有座山,山里有座廟,廟里有個和尚講故事,講的什么呢?從前有座山,山里有座廟,廟里有個和尚講故事,講的什么呢?……根據定義,這是典型的遞歸,同時也是一種遞推,在此過程中用到了迭代。在中文的語境,遞推暗含方向朝前(forward),而遞歸描述的是方向往回(back)。遞歸和遞推的共同點在于“遞”,強調使用相同算法更新迭代,所以二者在英文中是用分形來定義的。事實上,從嚴格的意義上講,遞歸除了有一般的自遞歸,還包括互遞歸。互遞歸,是通過調用其他函數間接地調用自身的過程。此外,在C語言中,還有一個嵌套函數的概念。所謂嵌套函數,指的是在某些情況下,可能需要將某函數作為另一函數的參數使用,這一函數就是嵌套函數。在一個函數被調用的過程中又調用另一個函數,這就是函數的嵌套調用。特別的,如果是函數本身嵌套調用函數本身,那就是函數遞歸調用了。遞歸調用是嵌套調用的特殊情形,遞歸調用的本質就是對同一個子程序(函數)的嵌套調用。接下來我們以c語言和匯編語言條件下求階乘n!為例。

可以很清楚地看到,C語言中的循環在匯編環境下是用簡單的:比較指令cmp+跳轉指令(如jmp)的組合來實現的,這與我們下面談到的遞歸方法有所不同。

這里略微復雜一些,C語言中的遞歸調用factorial(n-1)是用call指令完成的。我們知道,call調用一個子程序的步驟是push+jump,即在堆棧中先用eax保存參數n-1,再跳轉到函數入口f013813C0)循環調用.factorial。此過程與迭代的相同之處是都含有計數器和參數的變化、并且都有出口條件保iiEN環次數有限,不同的地方是:迭代過程更新的是所求未知量,循環結束就能求得目標結果;遞歸過程由兩部分組成,其分界線是到達函數出口(01381403)。前半部分壓棧操作(call)完成的只是參數的準備工作(1、2、3、……、n),后半部分彈棧操作(retn)完成的才是實際計算(resuh=lx2x3x……×n)。從形式上可以看出,迭代一般只是“0型”的循環結構,而遞歸則是“8型”的循環結構,換句話說是由兩個循環連接組成的,見圖1:子程序的調用過程。

我們發現,遞歸主要分為兩步,第一步是從目標出發回溯到源頭,稱為回歸。第二步是從源頭出發逐步回代達到目標,稱為遞推。這就必須保存子程序的變量、參數與返回地址,使程序能夠返回到調用處繼續執行。這一步是通過棧來實現的,做法是將函數的返回地址(也稱為“斷點”)即該函數下一條待執行指令的地址壓棧。反復call(調用)子程序相當于是“回歸”過程,多次執行ret(返回)指令就相當于“遞堆”過程。每一個call都會有一個ret與之對應,并且是某一級遞歸返回到調用它的那一級,而不是直接返回到main()函數中的初始調用部分。雖然每一級遞歸都有自己的變量和參數,但是函數代碼并不會復制,變化的主要是棧區的數據,下面我們用圖示來進一步觀察和分析。

遞歸算法實質就是一個函數不斷調用自身的過程,在調用過程中不斷地將局部變量、函數參數和返回地址壓人棧區,當返回時再將棧恢復到每一次調用前的狀態,每一層調用過程棧幀中存放的返回地址都是相同的(013813F9)。在整個的返回階段,始終以EAX寄存器作為橋梁,反復和棧交換數據,不斷地將中間結果保存在返回值中,從而實現參數的傳遞和結果的返回。

由此可見,遞歸確實是一種奇妙的思維方式。其優點是很顯然的:容易理解,容易編程。不過,PeterDeutsch(彼得·道奇)曾說:To Iterate is Human,to Recurse,Divine.(用迭代的是人,用遞歸的,是神。)他想表達的意思是:遞歸雖好,能夠用對卻不容易。當我們面對一個復雜問題的時候,應當想想能否將其轉化為較為簡單的同類問題呢?可以的話,就先轉換為簡單的同類問題來解決,然后再利用簡單的同類問題解法來解決復雜的同類問題,這就是遞歸思維方式的精髓所在。

遞歸的使用是有條件的。只有當算法存在預期的收斂效果時,采用遞歸算法才是可行的,否則,就不能使用遞歸算法。從數學角度講,有這幾種表達方式:函數具備收斂性=有確定的(或有限的)極限=極限是(確定的點或有限的數),對于計算機來說也一樣,要求約束條件必須收斂。簡而言之,循環次數是有限的,即有一個明確的邊界條件或臨界點,作為遞歸出口。為做到這一點,遞歸函數中必須包含終止遞歸的語句。通常遞歸函數會使用一個if條件語句或其他類似語句以便當函數參數達到某個特定值(如上例的n=1)時結束遞歸調用。

遞歸和循環是兩種不同的解決問題的思路。單從算法設計上講,遞歸和循環并無優劣之分。然而,在編程開發中,由于函數調用的開銷,遞歸常常會帶來性能問題,特別是在求解規模不確定的情況下;而循環因為沒有函數調用開銷,所以效率會比遞歸高。我們以計算Fibonacci(斐波那契)函數為例來說明。

對于應用程序而言,時間開銷和空間開銷是兩個重要的考察項目。從時間的角度來看,遞歸存在計算速度慢、執行時間長的弊端,時間復雜度0(2n)呈現指數級的增長,相比于循環的線性變化0(n)要高得多,原因在于不必要的重復計算。下圖是n=5時的遞歸樹(recursion tree),可以看出虛線框中Fibonacci(2)的計算用到了三次,同樣的Fibonacci(3)的計算用到了兩次,顯然我們進行了不少的重復運算。不得不考慮到,當n越大時,情況越嚴重。

從空間的角度來看,循環使用的是堆空間,而遞歸使用的是棧空間。循環占用的內存是一次性的,也就是O(1)的空間復雜度,而對于遞歸(不考慮尾遞歸優化的情況),每次函數調用都要壓棧,那么空間復雜度是O(n),和遞歸次數呈線性關系。

綜上所述,循環、迭代與遞歸、遞推這幾個概念既有聯系,又有區別。它們是人們解決復雜問題的思想方法,無論是在閱讀還是在表達時,不管是在學習還是在工作中,都應做到準確理解和正確使用。

主站蜘蛛池模板: 国模沟沟一区二区三区| 欧美色亚洲| 77777亚洲午夜久久多人| 亚洲福利视频网址| 99精品这里只有精品高清视频| 日韩色图区| 黑人巨大精品欧美一区二区区| 欧美啪啪精品| 国产在线自在拍91精品黑人| 又粗又硬又大又爽免费视频播放| 成人综合在线观看| 欧美色香蕉| 青青草国产一区二区三区| 婷婷午夜天| 9966国产精品视频| 成人国产精品2021| 极品国产一区二区三区| 亚洲va欧美va国产综合下载| 国内精自线i品一区202| 国产在线精彩视频二区| 欧美日韩在线国产| 九色视频一区| 国产欧美视频综合二区| 东京热一区二区三区无码视频| 久久久久亚洲AV成人人电影软件 | 精品福利视频网| 综合色区亚洲熟妇在线| jijzzizz老师出水喷水喷出| 日韩无码视频专区| 欧美成人在线免费| 自拍欧美亚洲| 欧美伦理一区| 片在线无码观看| 18禁色诱爆乳网站| 久久久精品久久久久三级| 亚洲第一色视频| 亚洲天堂久久| 亚洲天堂视频在线观看免费 | 女人天堂av免费| 午夜丁香婷婷| 亚洲成人精品在线| 亚洲毛片在线看| 在线观看免费AV网| 97视频免费在线观看| 成人午夜精品一级毛片| 四虎成人精品在永久免费| 蝴蝶伊人久久中文娱乐网| 极品av一区二区| 成人久久18免费网站| 亚洲综合专区| 日本三级欧美三级| 日本人妻一区二区三区不卡影院 | 欧美国产日韩在线| 国产精品人成在线播放| 视频二区国产精品职场同事| 伊人久综合| 国产视频一区二区在线观看| 国产草草影院18成年视频| 久草国产在线观看| 国产精品v欧美| 欧美特级AAAAAA视频免费观看| 亚洲色精品国产一区二区三区| 国产波多野结衣中文在线播放 | 国产在线麻豆波多野结衣| 成人蜜桃网| 成人午夜网址| 国内精自线i品一区202| 国产偷国产偷在线高清| 国产精品.com| 欧美第一页在线| 亚洲欧美不卡| 国产呦视频免费视频在线观看| 国产另类视频| 亚洲综合久久成人AV| 99热这里只有精品久久免费| 国产欧美视频在线| 日本在线亚洲| 久久黄色一级片| 在线观看热码亚洲av每日更新| 欧美视频在线不卡| 国产你懂得| 欧美综合一区二区三区|