導航:首頁 > 源碼編譯 > 用遞歸設計的演算法效率

用遞歸設計的演算法效率

發布時間:2025-05-29 16:28:37

㈠ 程序的遞歸演算法與非遞歸的區別

1、遞歸和非遞歸(用棧) 非遞歸(用棧),也用到棧函數了,和遞歸就沒多大區別了! 每次遞歸進棧出棧,非遞歸(用棧)的每次調用棧函數也是進棧出棧。主要是在非遞歸(用棧)中,它的棧函數里比遞歸多了些賦值語句。。。所以效率上,非遞歸(用棧)比遞歸差。 只不過,遞歸越深,佔用棧空間越多。非遞歸(用棧),佔用的棧空間少。如果,遞歸的深度還沒達到超出棧空間的程度,那麼遞歸比非遞歸(用棧)好。 如果是非遞歸(不用棧),當然是非遞歸最好。 在下面的這個例子(解決「整數劃分問題」)中,說明了如果只是用棧機械的模擬,得到的結果只是: 空間不變(事實上,非遞歸應該多一些),而非遞歸的時間數倍的增加。。 感興趣的朋友運行就知道了 #include<iostream> #include<stack> #include<ctime> using namespace std; //---------------------------遞歸演算法 int q(int n,int m) { if((n<1) || (m<0)) return 0; if((n==1) ||(m==1)) return 1; if(n<m) return q(n,n); if(n==m) return q(n,m-1)+1; return q(n,m-1)+q(n-m,m); } int q(int num) { return q(num,num); } struct Point { int n,m; Point(int _n,int _m){ n=_n; m=_m;} }; //-------------------------非遞歸演算法 int _q(int n,int m) { int sum=0; Point tmp(n,m); stack<Point> s; s.push (tmp); while(!s.empty()) { tmp=s.top(); n=tmp.n; m=tmp.m; s.pop(); if((n<1) || (m<0)) ++sum; else if((n==1) ||(m==1)) ++sum; else if(n<m) s.push(Point(n,n)); else if(n==m) { ++sum; s.push(Point(n,m-1)); } else { s.push(Point(n,m-1)); s.push(Point(n-m,m)); } } return sum; } int _q(int num) { return _q(num,num); } int main() { int num; unsigned int p; do{ cout<<"Input a num:"; cin>>num; p=clock(); cout<<" 遞歸: "<<q(num)<<endl; cout<<"\t\t用時:"<<clock()-p<<endl; p=clock(); cout<<"非遞歸: "<<_q(num)<<endl; cout<<"\t\t用時:"<<clock()-p<<endl<<endl; }while(num); return 0; } 2. 如果非遞歸不是用棧做的 這里有一個網友做的漢諾塔問題的非遞歸解法 看了真讓人汗顏 這樣的規律都有人發現 下載地址是: http://wenku..com/view/cfd56b3610661ed9ad51f3f9.html 此演算法不是用大家以前熟悉的遞歸演算法 雖然沒運行 可以猜想 這個程序的空間和時間效率毫無疑問會大幅度提高。 3. 總結: 直接引用《演算法設計與分析(第二版)》里的一段話: 結構清晰,可讀性強,而且容易用數學歸納法來證明演算法的正確性,而且它為設計演算法,調試程序帶來很大方便。 然而遞歸演算法的運行效率較低,無論是耗費的計算時間還是佔用的存儲空間都比非遞歸演算法要多 僅僅是機械地模擬還不能達到減少計算時間和存儲空間的目的。因此,還需要根據具體程序和特點對遞歸調用的工作棧進行簡化,盡量減少棧的操作,壓縮棧存儲以達到節省計算時間和存儲空間的目的。

㈡ 遞歸演算法

遞歸演算法
遞歸演算法流程
遞歸過程一般通過函數或子過程來實現。遞歸演算法:在函數或子過程的內部,直接或者間接地調用自己的演算法。
遞歸演算法的特點
遞歸演算法是一種直接或者間接地調用自身的演算法。在計算機編寫程序中,遞歸演算法對解決一大類問題是十分有效的,它往往使演算法的描述簡潔而且易於理解。 遞歸演算法解決問題的特點: (1) 遞歸就是在過程或函數里調用自身。 (2) 在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱為遞歸出口。 (3) 遞歸演算法解題通常顯得很簡潔,但遞歸演算法解題的運行效率較低。所以一般不提倡用遞歸演算法設計程序。 (4) 在遞歸調用的過程當中系統為每一層的返回點、局部量等開辟了棧來存儲。遞歸次數過多容易造成棧溢出等。所以一般不提倡用遞歸演算法設計程序。
遞歸演算法要求
遞歸演算法所體現的「重復」一般有三個要求: 一是每次調用在規模上都有所縮小(通常是減半); 二是相鄰兩次重復之間有緊密的聯系,前一次要為後一次做准備(通常前一次的輸出就作為後一次的輸入); 三是在問題的規模極小時必須用直接給出解答而不再進行遞歸調用,因而每次遞歸調用都是有條件的(以規模未達到直接解答的大小為條件),無條件遞歸調用將會成為死循環而不能正常結束。
舉例
描述:把一個整數按n(2<=n<=20)進製表示出來,並保存在給定字元串中。比如121用二進製表示得到結果為:「1111001」。 參數說明:s: 保存轉換後得到的結果。 n: 待轉換的整數。 b: n進制(2<=n<=20) void numbconv(char *s, int n, int b) { int len; if(n == 0) { strcpy(s, ""); return; } /* figure out first n-1 digits */ numbconv(s, n/b, b); /* add last digit */ len = strlen(s); s[len] = ""[n%b]; s[len+1] = '\0'; } void main(void) { char s[20]; int i, base; FILE *fin, *fout; fin = fopen("palsquare.in", "r"); fout = fopen("palsquare.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d", &base); /*PLS set START and END*/ for(i=START; i <= END; i++) { numbconv(s, i*i, base); fprintf(fout, "%s\n", s); } exit(0); }
編輯本段遞歸演算法簡析(PASCAL語言)
遞歸是計算機科學的一個重要概念,遞歸的方法是程序設計中有效的方法,採用遞歸編寫 程序能是程序變得簡潔和清晰.
一 遞歸的概念
1.概念 一個過程(或函數)直接或間接調用自己本身,這種過程(或函數)叫遞歸過程(或函數). 如: procere a; begin . . . a; . . . end; 這種方式是直接調用. 又如: procere c(形參);forward; procere b; 局部說明 begin . . c(實參); . . end; procere c; 局部說明; begin . . b; . . end; 這種方式是間接調用. 例1計算n!可用遞歸公式如下: fac:=n*fac(n-1) {當n>0時} fac(n)={ fac:=1; { 當n=0時} 可編寫程序如下: program facn; var n:integer; function fac(n:integer):real; begin if n=0 then fac:=1 else fac:=n*fac(n-1); end; begin write('n=');readln(n); writeln(n,'!=',fac(n):0:0); end. 例2 樓梯有n階台階,上樓可以一步上1階,也可以一步上2階,編一程序計算共有多少種不同的走法. 設n階台階的走法數為f(n) 顯然有 n=1 f(n)={ f(n-1)+f(n-2) n>2 可編程序如下: program louti; var n:integer; function f(x:integer):integer; begin if x=1 then f:=1 else if x=2 then f:=2 else f:=f(x-1)+f(x-2); end; begin write('n=');read(n); writeln('f(',n,')=',f(n)) end.
二 如何設計遞歸演算法
1.確定遞歸公式 2.確定邊界(終了)條件
三 典型例題
例3 漢諾塔問題 如圖:已知有三根針分別用1,2,3表示,在一號針中從小放n個盤子,現要求把所有的盤子 從1針全部移到3針,移動規則是:使用2針作為過度針,每次只移動一塊盤子,且每根針上 不能出現大盤壓小盤.找出移動次數最小的方案. 程序如下: program hanoi; var n:integer; procere move(n,a,b,c:integer); begin if n=1 then writeln(a,'->',c) else begin move(n-1,a,c,b); writeln(a,'--->',c); move(n-1,b,a,c); end; end; begin write('Enter n='); read(n); move(n,1,2,3); end. 例4 快速排序 快速排序的思想是:先從數據序列中選一個元素,並將序列中所有比該元素小的元素都放到它的右邊或左邊,再對左右兩邊分別用同樣的方法處之直到每一個待處理的序列的長度為1, 處理結束. 程序如下: program kspv; const n=7; type arr=array[1..n] of integer; var a:arr; i:integer; procere quicksort(var b:arr; s,t:integer); var i,j,x,t1:integer; begin i:=s;j:=t;x:=b ; repeat while (b[j]>=x) and (j>i) do j:=j-1; if j>i then begin t1:=b; b:=b[j];b[j]:=t1;end; while (b<=x) and (i<j) do i:=i+1; if i<j then begin t1:=b[j];b[j]:=b;b:=t1; end until i=j; b:=x; i:=i+1;j:=j-1; if s<j then quicksort(b,s,j); if i<t then quicksort(b,i,t); end; begin write('input data:'); for i:=1 to n do read(a); writeln; quicksort(a,1,n); write('output data:'); for i:=1 to n do write(a:6); writeln; end.
編輯本段{遞歸的一般模式}
procere aaa(k:integer); begin if k=1 then (邊界條件及必要操作) else begin aaa(k-1); (重復的操作); end; end;
開放分類:
編程,計算機,演算法

引自:http://ke..com/view/1733593.htm

閱讀全文

與用遞歸設計的演算法效率相關的資料

熱點內容
寶可夢做解壓視頻 瀏覽:594
威綸通觸摸屏編譯時內存不足 瀏覽:608
單片機採集電壓比較 瀏覽:948
程序員三年前工資多少 瀏覽:705
pc端c語言編譯工具 瀏覽:22
護理知識app怎麼做 瀏覽:29
我的世界伺服器如何跨版本 瀏覽:912
益盟正版主力識別公式源碼 瀏覽:491
溫州程序員兼職網站 瀏覽:718
csgo控制台命令大全指令表 瀏覽:730
小米盒子連接伺服器地址 瀏覽:366
文檔怎麼壓縮進一個文件夾 瀏覽:84
cnn新聞app從哪裡下載 瀏覽:71
殺戮命令精通 瀏覽:894
如何查魔獸世界角色在哪個伺服器 瀏覽:43
壓縮氣罐免責說明 瀏覽:912
為什麼sim連接不了伺服器 瀏覽:31
如何注冊豆瓣app 瀏覽:558
屏膜找圖演算法 瀏覽:538
我的世界伺服器怎麼給別人游戲幣 瀏覽:940