歡迎來到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁 裝配圖網(wǎng) > 資源分類 > PPT文檔下載  

《數(shù)據(jù)結(jié)構(gòu)C語言版》-第06章.ppt

  • 資源ID:15848143       資源大?。?span id="vxkrd5k" class="font-tahoma">402.06KB        全文頁數(shù):42頁
  • 資源格式: PPT        下載積分:9.9積分
快捷下載 游客一鍵下載
會員登錄下載
微信登錄下載
三方登錄下載: 微信開放平臺登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要9.9積分
郵箱/手機:
溫馨提示:
用戶名和密碼都是您填寫的郵箱或者手機號,方便查詢和重復下載(系統(tǒng)自動生成)
支付方式: 支付寶    微信支付   
驗證碼:   換一換

 
賬號:
密碼:
驗證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會被瀏覽器默認打開,此種情況可以點擊瀏覽器菜單,保存網(wǎng)頁到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無水印,預覽文檔經(jīng)過壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標題沒有明確說明有答案則都視為沒有答案,請知曉。

《數(shù)據(jù)結(jié)構(gòu)C語言版》-第06章.ppt

1,第6章 遞歸算法,遞歸的概念 遞歸算法的執(zhí)行過程 遞歸算法的設(shè)計方法 遞歸過程和運行時棧 遞歸算法的效率分析 設(shè)計舉例,主要知識點,2,存在算法調(diào)用自己的情況:,若一個算法直接的或間接的調(diào)用自己本身,則稱這個算法是遞歸算法。,(1)問題的定義是遞推的,階乘函數(shù)的常見定義是:,6.1遞歸的概念,3,也可定義為:,寫成函數(shù)形式,則為:,這種函數(shù)定義的方法是用階乘函數(shù)自己本身定義了階乘函數(shù),稱公式(6 3)是階乘函數(shù)的遞推定義式。,4,(2)問題的解法存在自調(diào)用,一個典型的例子是在有序數(shù)組中查找一個數(shù)據(jù)元素是否存在的折半查找算法。,5,圖6-1 折半查找過程,6,6.2遞歸算法的執(zhí)行過程,例6-1 給出按照公式6-3計算階乘函數(shù)的遞歸算法,并給出n = 3時遞歸算法的執(zhí)行過程。 設(shè)計:按照公式6-3計算階乘函數(shù)的遞歸算法如下:,7,long int Fact(int n) int x; long int y; if(n < 0) /n < 0時階乘無定義 printf(“參數(shù)錯!”); return -1; if(n = 0) return 1; else y = Fact(n - 1); /遞歸調(diào)用 return n * y; ,8,設(shè)計主函數(shù)如下,void main(void) long int fn; fn = Fact(3); ,主函數(shù)用實參n= 3調(diào)用了遞歸算法Fact(3),而Fact(3)要通過調(diào)用Fact(2)、Fact(2)要通過調(diào)用Fact(1)、Fact(1)要通過調(diào)用Fact(0)來得出計算結(jié)果。Fact(3)的遞歸調(diào)用過程如圖6-2所示。,9,圖6-2 Fact(3)的遞歸調(diào)用執(zhí)行過程,10,例6-2 給出在有序數(shù)組a中查找數(shù)據(jù)元素x是否存在的遞歸算法,并給出如圖6-1所示實際數(shù)據(jù)的遞歸算法的執(zhí)行過程。遞歸算法如下:,11,int BSearch(int a, int x, int low, int high) int mid; if(low high) return -1;/查找不成功 mid = (low + high) / 2; if(x = amid)return mid;/查找成功 else if(x < amid) return BSearch(a, x, low, mid-1);/在下半?yún)^(qū)查找 else return BSearch(a, x, mid+1, high);/在上半?yún)^(qū)查找 ,12,測試主函數(shù)設(shè)計如下: # include main(void) int a = 1, 3, 4, 5, 17, 18, 31, 33; int x = 17; int bn; bn = BSearch(a, x, 0,7); if(bn = -1) printf(x不在數(shù)組a中); else printf(x在數(shù)組a的下標%d中, bn); ,13,BSearch(a, x, 0,7)的遞歸調(diào)用過程如圖6-3所示,其中,實箭頭表示函數(shù)調(diào)用,虛箭頭表示函數(shù)的返回值。,圖6-3 BSearch(a, x, 0,7)的遞歸調(diào)用過程,14,15,6.3遞歸算法的設(shè)計方法,遞歸算法既是一種有效的算法設(shè)計方法,也是一種有效的分析問題的方法。 遞歸算法求解問題的基本思想是:對于一個較為復雜的問題,把原問題分解成若干個相對簡單且類同的子問題,這樣,原問題就可遞推得到解。,16,適宜于用遞歸算法求解的問題的充分必要條件是: (1)問題具有某種可借用的類同自身的子問題描述的性質(zhì); (2)某一有限步的子問題(也稱作本原問題)有直接的解存在。 當一個問題存在上述兩個基本要素時,該問題的遞歸算法的設(shè)計方法是: (1)把對原問題的求解設(shè)計成包含有對子問題求解的形式。 (2)設(shè)計遞歸出口。,17,例6-3 設(shè)計模擬漢諾塔問題求解過程的算法。漢諾塔問題的描述是:設(shè)有3根標號為A,B,C的柱子,在A柱上放著n個盤子,每一個都比下面的略小一點,要求把A柱上的盤子全部移到C柱上,移動的規(guī)則是: (1)一次只能移動一個盤子; (2)移動過程中大盤子不能放在小盤子上面; (3)在移動過程中盤子可以放在A,B,C的任意一個柱子上。,18,問題分析: 可以用遞歸方法求解n個盤子的漢諾塔問題。 基本思想: 1個盤子的漢諾塔問題可直接移動。n個盤子的漢諾塔問題可遞歸表示為,首先把上邊的n-1個盤子從A柱移到B柱,然后把最下邊的一個盤子從A柱移到C柱,最后把移到B柱的n-1個盤子再移到C柱。4個盤子漢諾塔問題的遞歸求解示意圖如圖6-4所示。,19,圖6-4 漢諾塔問題的遞歸求解示意圖,20,算法設(shè)計:首先,盤子的個數(shù)n是必須的一個輸入?yún)?shù),對n個盤子,我們可從上至下依次編號為1,2,n;其次,輸入?yún)?shù)還需有3個柱子的代號,我們令3個柱子的參數(shù)名分別為fromPeg,auxPeg和toPeg;最后,漢諾塔問題的求解是一個處理過程,因此算法的輸出是n個盤子從柱子fromPeg借助柱子auxPeg移動到柱子toPeg的移動步驟,我們設(shè)計每一步的移動為屏幕顯示如下形式的信息: Move Disk i from Peg X to Peg Y 這樣,漢諾塔問題的遞歸算法可設(shè)計如下:,21,void towers(int n, char fromPeg, char toPeg, char auxPeg) if(n=1)/遞歸出口 printf(%s%c%s%cn, move disk 1 from peg , fromPeg, to peg , toPeg); return; /把n-1個圓盤從fromPeg借助toPeg移至auxPeg towers(n-1,fromPeg,auxPeg,toPeg); /把圓盤n由fromPeg直接移至toPeg printf(%s%d%s%c%s%cn, move disk , n, from peg , fromPeg, to peg , toPeg); /把n-1個圓盤從auxPeg借助fromPeg移至toPeg towers(n-1,auxPeg,toPeg,fromPeg); ,22,測試主函數(shù)如下: #include void main(void) Towers(4, A, C, B); 程序運行的輸出信息如下:,23,Move Disk 1 from Peg A to Peg B Move Disk 2 from Peg A to Peg C Move Disk 1 from Peg B to Peg C Move Disk 3 from Peg A to Peg B Move Disk 1 from Peg C to Peg A Move Disk 2 from Peg C to Peg B Move Disk 1 from Peg A to Peg B Move Disk 4 from Peg A to Peg C Move Disk 1 from Peg B to Peg C Move Disk 2 from Peg B to Peg A Move Disk 1 from Peg C to Peg A Move Disk 3 from Peg B to Peg C Move Disk 1 from Peg A to Peg B Move Disk 2 from Peg A to Peg C Move Disk 1 from Peg B to Peg C,24,總結(jié)如下:遞歸算法的執(zhí)行過程是不斷地自調(diào)用,直到到達遞歸出口才結(jié)束自調(diào)用過程;到達遞歸出口后,遞歸算法開始按最后調(diào)用的過程最先返回的次序返回;返回到最外層的調(diào)用語句時遞歸算法執(zhí)行過程結(jié)束。,25,6.4遞歸過程和運行時棧,對于非遞歸函數(shù),調(diào)用函數(shù)在調(diào)用被調(diào)用函數(shù)前,系統(tǒng)要保存以下兩類信息: (1)調(diào)用函數(shù)的返回地址; (2)調(diào)用函數(shù)的局部變量值。 當執(zhí)行完被調(diào)用函數(shù),返回調(diào)用函數(shù)前,系統(tǒng)首先要恢復調(diào)用函數(shù)的局部變量值,然后返回調(diào)用函數(shù)的返回地址。,26,遞歸函數(shù)被調(diào)用時,系統(tǒng)要作的工作和非遞歸函數(shù)被調(diào)用時系統(tǒng)要作的工作在形式上類同,但保存信息的方法不同。 遞歸函數(shù)被調(diào)用時,系統(tǒng)需要一個運行時棧.系統(tǒng)的運行時棧也要保存上述兩類信息。每一層遞歸調(diào)用所需保存的信息構(gòu)成運行時棧的一個工作記錄,在每進入下一層遞歸調(diào)用時,系統(tǒng)就建立一個新的工作記錄,并把這個工作記錄進棧成為運行時棧新的棧頂;每返回一層遞歸調(diào)用,就退棧一個工作記錄。因為棧頂?shù)墓ぷ饔涗洷囟ㄊ钱斍罢谶\行的遞歸函數(shù)的工作記錄,所以棧頂?shù)墓ぷ饔涗浺卜Q為活動記錄。,27,6.5遞歸算法的效率分析,斐波那契數(shù)列Fib(n)的遞推定義是:,求第n項斐波那契數(shù)列的遞歸函數(shù)如下:,long Fib(int n) if(n = 0 | n = 1) return n; /遞歸出口 else return Fib(n-1) + Fib(n-2); /遞歸調(diào)用 ,28,用歸納法可以證明求Fib(n)的遞歸調(diào)用次數(shù)等于2n-1;計算斐波那契數(shù)列的遞歸函數(shù)Fib(n)的時間復雜度為O(2n)。計算斐波那契數(shù)列Fib(n)問題,我們也可根據(jù)公式寫出循環(huán)方式求解的函數(shù)如下:,圖6-6 Fib(5)的遞歸調(diào)用樹,29,long Fib2(int n) long int oneBack, twoBack, current; int i; if(n = 0 | n = 1) return n; else oneBack = 1; twoBack = 0; for(i = 2; i <= n; i+) current = oneBack + twoBack; twoBack = oneBack; oneBack = current; return current; ,30,上述循環(huán)方式的計算斐波那契數(shù)列的函數(shù)Fib2(n)的時間復雜度為O(n)。對比循環(huán)結(jié)構(gòu)的Fib2(n)和遞歸結(jié)構(gòu)的Fib(n)可發(fā)現(xiàn),循環(huán)結(jié)構(gòu)的Fib2(n)算法在計算第n項的斐波那契數(shù)列時保存了當前已經(jīng)計算得到的第n-1項和第n-2項的斐波那契數(shù)列,因此其時間復雜度為O(n);而遞歸結(jié)構(gòu)的Fib(n)算法在計算第n項的斐波那契數(shù)列時,必須首先計算第n-1項和第n-2項的斐波那契數(shù)列,而某次遞歸計算得出的斐波那契數(shù)列,如Fib(n-1)、Fib(n-2)等無法保存,下一次要用到時還需要重新遞歸計算,因此其時間復雜度為O(2n) 。,31,*6.6遞歸算法到非遞歸算法的轉(zhuǎn)換,有些問題需要用低級程序設(shè)計語言來實現(xiàn),而低級程序設(shè)計語言(如匯編語言)一般不支持遞歸,此時需要采用問題的非遞歸結(jié)構(gòu)算法。一般來說,存在如下兩種情況的遞歸算法。 (1)存在不借助堆棧的循環(huán)結(jié)構(gòu)的非遞歸算法,如階乘計算問題、斐波那契數(shù)列的計算問題、折半查找問題等。這種情況,可以直接選用循環(huán)結(jié)構(gòu)的算法。,32,(2)存在借助堆棧的循環(huán)結(jié)構(gòu)的非遞歸算法,所有遞歸算法都可以借助堆棧轉(zhuǎn)換成循環(huán)結(jié)構(gòu)的非遞歸算法,如下邊例6-4設(shè)計的漢諾塔問題的借助堆棧的循環(huán)結(jié)構(gòu)的非遞歸算法。此時可以把遞歸算法轉(zhuǎn)換成相應的非遞歸算法,有兩種轉(zhuǎn)換方法:一種方法是借助堆棧,用非遞歸算法形式化模擬遞歸算法的執(zhí)行過程;另一種方法是根據(jù)要求解問題的特點,設(shè)計借助堆棧的循環(huán)結(jié)構(gòu)算法。這兩種方法都需要使用堆棧,這是因為堆棧的后進先出特點正好和遞歸函數(shù)的運行特點相吻合。下面討論的例6-4是第二種情況下的第一種轉(zhuǎn)換方法的例子,33,6.7設(shè)計舉例,6.7.1 一般遞歸算法設(shè)計舉例,例6-5 設(shè)計一個輸出如下形式數(shù)值的遞歸算法。 n n n . n . 3 3 3 2 2 1,34,問題分析:該問題可以看成由兩部分組成:一部分是輸出一行值為n的數(shù)值;另一部分是原問題的子問題,其參數(shù)為n-1。當參數(shù)減到0時不再輸出任何數(shù)據(jù)值,因此遞歸的出口是當參數(shù)n0時空語句返回。,算法設(shè)計:遞歸算法設(shè)計如下: void Display(int n) int i; for(i = 1; i 0) Display(n - 1);/遞歸 /n<=0為遞歸出口,遞歸出口為空語句 ,35,例6-6 設(shè)計求解委員會問題的算法。委員會問題是:從一個有n個人的團體中抽出k (kn)個人組成一個委員會,計算共有多少種構(gòu)成方法。 問題分析:從n個人中抽出k(kn)個人的問題是一個組合問題。把n個人固定位置后,從n個人中抽出k個人的問題可分解為兩部分之和:第一部分是第一個人包括在k個人中,第二部分是第一個人不包括在k個人中。對于第一部分,則問題簡化為從n-1個人中抽出k-1個人的問題;對于第二部分,則問題簡化為從n-1個人中抽出k個人的問題。圖6-7給出了n=5, k=2時問題的分解示意圖。,36,圖6-7 委員會問題分解示意圖,37,當n=k或k=0時,該問題可直接求解,數(shù)值均為1,這是算法的遞歸出口。因此,委員會問題的遞推定義式為:,38,int Comm(int n, int k) if(n n) return 0; if(k = 0) return 1; if(n = k) return 1; return Comm(n-1, k-1) + Comm(n-1, k); ,39,例6-7 求兩個正整數(shù)n和m最大公約數(shù)的遞推定義式為:,要求: (1)編寫求解該問題的遞歸算法; (2)分析當調(diào)用語句為Gcd(30, 4)時算法的執(zhí)行過程和執(zhí)行結(jié)果; (3)分析當調(diào)用語句為Gcd(97, 5)時算法的執(zhí)行過程和執(zhí)行結(jié)果; (4)編寫求解該問題的循環(huán)結(jié)構(gòu)算法。,40,解:(1)遞歸算法如下: int Gcd(int n, int m) if(n n) return Gcd(m, n); else return Gcd(m, n % m); ,41,(2)調(diào)用語句為Gcd(30, 4)時,因mn,遞歸調(diào)用Gcd(97, 5);因m<n,遞歸調(diào)用Gcd(5, 2);因m<n,遞歸調(diào)用Gcd(2, 1);因m<n,遞歸調(diào)用Gcd(1, 0);因m=0,到達遞歸出口,函數(shù)最終返回值為n=1,即5和97的最大公約數(shù)為1。,42,6.7.2 回溯法及其設(shè)計舉例,回溯法是遞歸算法的一種特殊形式,回溯法的基本思想是:對一個包括有很多結(jié)點,每個結(jié)點有若干個搜索分支的問題,把原問題分解為對若干個子問題求解的算法。當搜索到某個結(jié)點、發(fā)現(xiàn)無法再繼續(xù)搜索下去時,就讓搜索過程回溯退到該結(jié)點的前一結(jié)點,繼續(xù)搜索這個結(jié)點的其他尚未搜索過的分支;如果發(fā)現(xiàn)這個結(jié)點也無法再繼續(xù)搜索下去時,就讓搜索過程回溯(即退回)到這個結(jié)點的前一結(jié)點繼續(xù)這樣的搜索過程;這樣的搜索過程一直進行到搜索到問題的解或搜索完了全部可搜索分支沒有解存在為止。,

注意事項

本文(《數(shù)據(jù)結(jié)構(gòu)C語言版》-第06章.ppt)為本站會員(w****2)主動上傳,裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng)(點擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因為網(wǎng)速或其他原因下載失敗請重新下載,重復下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!