A. 遞歸演算法 求詳細過程
遞歸演算法是把問題轉化為規模縮小了的同類問題的子問題。然後遞歸調用函數(或過程)來表示問題的解。
遞歸演算法解決問題的特點:
(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);
}
C#:例子
例:一列數的規則如下: 1、1、2、3、5、8、13、21、34...... 求第30位數是多少。
public class MainClass
{
public static void Main()
{
Console.WriteLine(Foo(30));
}
public static int Foo(int i)
{
if (i <= 0)
return 0;
else if(i > 0 && i <= 2)
return 1;
else return Foo(i -1) + Foo(i - 2);
}
}
B. 遞歸演算法要有哪兩個要素
終止條件和遞推公式。
C. 按要求設計遞歸演算法。只需寫出偽代碼或畫流程圖,不需語言實現,但演算法必須完整清晰。
arrs[100000][100000];
a[100000];
f(i,){
if(i==4){
arrs[]=a;
return;
}
a[i]=;
f(i+1,+3);
f(i+1,+4);
}
f(0,0)
arrs就是結果,並且是排了序的。
D. 一個遞歸演算法必須包括什麼
遞歸演算法包含的兩個部分:
1、由其自身定義的與原始問題類似的更小規模的子問題(只有數據規模不同),它使遞歸過程持續進行,稱為一般條件。
2、所描述問題的最簡單的情況,它是一個能控制遞歸過程結束的條件,稱為基本條件。(遞歸出口)
遞歸的定義:
如果一個對象部分地由它自身組成或按它自己定義,則稱它是遞歸的,所以說遞歸就是函數/過程/子過程在運行過程中直接或間接調用自身而產生的重入現象。
遞歸的基本思想:
就是把一個規模大的問題分為若干個規模較小的子問題求解,而每一個子問題又可以分為幾個規模更小的子問題。基本上,所有的遞歸問題都可以用遞推公式來表示。
最重要的一點就是假設子問題已經解決了,現在要基於已經解決的子問題來解決當前問題;或者說,必須先解決子問題,再基於子問題來解決當前問題或者可以這么理解:遞歸解決的是有依賴順序關系的多個問題。
遞歸的優缺點:
優點:邏輯清楚,結構清晰,可讀性好,代碼簡潔,效率高(拓展:DFS深度優先搜素,前中後序二叉樹遍歷)
缺點:函數調用開銷大,空間復雜度高,有堆棧溢出的風險
E. java中遞歸演算法是什麼怎麼算的
Java遞歸演算法是基於Java語言實現的遞歸演算法。遞歸演算法是一種直接或者間接調用自身函數或者方法的演算法。遞歸演算法實質是把問題分解成規模縮小的同類問題的子問題,然後遞歸調用方法表示問題的解。遞歸往往能給我們帶來非常簡潔非常直觀的代碼形式,從而使我們的編碼大大簡化,然而遞歸的思維確實跟我們的常規思維相逆的,通常都是從上而下的思維問題,而遞歸趨勢從下往上的進行思維。
二、遞歸演算法解決問題的特點:
【1】遞歸就是方法里調用自身。
【2】在使用遞歸策略時,必須有一個明確的遞歸結束條件,稱為遞歸出口。
【3】遞歸演算法代碼顯得很簡潔,但遞歸演算法解題的運行效率較低。所以不提倡用遞歸設計程序。
【4】在遞歸調用的過程中系統為每一層的返回點、局部量等開辟了棧來存儲。遞歸次數過多容易造成棧溢出等,所以一般不提倡用遞歸演算法設計程序。
【5】在做遞歸演算法的時候,一定把握出口,也就是做遞歸演算法必須要有一個明確的遞歸結束條件。這一點是非常重要的。其實這個出口就是一個條件,當滿足了這個條件的時候我們就不再遞歸了。
三、代碼示例:
代碼執行流程圖如下:
此程序中n=5就是程序的出口。
F. 選擇題:一個遞歸演算法必須包括()
一個遞歸演算法必須包括B、終止條件和遞歸部分。
遞歸演算法在計算機科學中是指一種通過重復將問題分解為同類的子問題而解決問題的方法。
遞歸式方法可以被用於解決很多的計算機科學問題,因此它是計算機科學中十分重要的一個概念。絕大多數編程語言支持函數的自調用,在這些語言中函數可以通過調用自身來進行遞歸。
尾部遞歸:
遞歸函數在調用自身後直接傳回其值,而不對其再加運算。尾部遞歸與循環是等價的,而且在一些語言(如Scheme中)可以被優化為循環指令。
因此,在這些語言中尾部遞歸不會佔用調用堆棧空間。以下Scheme程序同樣計算一個數字的階乘,但是使用尾部遞歸。
G. 一個遞歸演算法必須包括什麼
一個遞歸演算法必須包括終止條件和遞歸部分。
一般循環就是:
int multi = 1;
if (x <=1) return (1);
for(int i=1;i<=x;i++)multi = multi*i;
return(multi);
遞歸把x!看作x*(x-1)!
int multi(int x){if(x==0||x==1) return 1;else return x*multi(x-1);}
尾部遞歸:
而不對其再加運算。尾部遞歸與循環是等價的,而且在一些語言(如Scheme中)可以被優化為循環指令。
在這些語言中尾部遞歸不會佔用調用堆棧空間。以下Scheme程序同樣計算一個數字的階乘,但是使用尾部遞歸:(define(factorialn)(define(iterproctcounter)(if(>countern)proct(iter(*counterproct)(+counter1))))(iter11))。
H. 遞歸演算法必須包括什麼
遞歸演算法,必須包含遞歸過程,也必須包括退出遞歸的條件。
I. 07《演算法入門教程》遞歸演算法
本節內容是遞歸演算法系列之一:遞歸的介紹,主要介紹了遞歸的定義,選擇了數學歸納法這一數學模型幫助大家可以更好的理解遞歸的概念,然後明確了一個遞歸演算法必須要具備的三要素,最後說明了一下哪些問題適合應用遞歸演算法求解分析。
遞歸(Recursion),是計算機科學與技術領域中一種常見的演算法思想。
在數學和計算機領域中,遞歸主要是指在函數的定義中使用函數自身的方法。顧名思義,遞歸主要包含兩個意思, 遞 和 歸 ,這個是遞歸思想的精華所在。遞歸就是有去(遞去)有回(歸來)。「有去」 是指遞歸問題可以分解成若干個規模較小、與原問題形式相同的子問題,這些子問題可以和原問題用相同的方法來求解。「有回」 是指這些問題的演化過程是一個從大到小,並且最終會有一個明確的終點,一旦達到終點,就可以從終點原路返回,解決原問題。
很多時候,大家都在思考遞歸在數學上面應該如何表示了,畢竟對於數學的簡單理解比起我們直接寫代碼起來還是要簡單很多的。觀察遞歸,我們會很容易發現遞歸的數學模型類似於 數學歸納法 ,這個在高中的數列裡面就已經開始應用了。數學歸納法常見的描述如下
數學歸納法適用於將需要解決的原問題轉換為解決他的子問題,而其中的子問題又可以變成子問題的子問題,而且這些問題都是同一個模型,可以用相同的處理邏輯歸納處理。當然有一個是例外的,就是歸納結束的那一個處理方法不能適用於其他的歸納處理項。遞歸同樣的是將大的問題分解成小問題處理,然後會有一個遞歸的終止條件,滿足終止條件之後開始回歸。
數學裡面有一個很有名的斐波那契數列,我們在編程求解斐波那契數列的時候就會用到遞歸的思想,在後續的內部中會具體講到。
在明確遞歸的定義及數學模型之後,我們需要掌握遞歸的三要素:
按照之前的說明,遞歸應該是有去有回的,這樣遞歸就必須有一個明確的分界點,遞歸可以在什麼時候結束。程序一旦達到這個臨界點,就不用繼續遞歸重復下去了。簡單來說,遞歸的終止條件就是為了防止出現無限遞歸的情況。
如前面說到遞歸需要一個終止條件一樣,在達到遞歸的終止條件時,需要有一個對應終止條件的程序處理方法。一般而言,在達到遞歸的終止條件時,對應的問題都是很容易解決的,可以快速的給出問題的解決方案。
遞歸的本質上還是要將一個大的問題分解成各個邏輯相同的小問題,所以遞歸過程中一個重要的步驟就是提取遞歸中重復的邏輯規則,以便利用相同的處理方式進行處理。
按照以上遞歸的三要素,遞歸程序的一般處理可以總結成下面的偽代碼:
在日常的生活學習中,遞歸演算法一般可以用來解決很多實際問題。回顧一下我們之前學習的排序演算法,其中快速排序利用了遞歸的思想進行解決。總而言之,遞歸在很多場景中都有應用。
比如說一個常見的對於操作系統裡面刪除指定路徑下的文件夾里內容以及子文件夾裡面內容的操作,就可以利用遞歸思想完成。這個時候遞歸的終止條件就是判斷當前路徑是文件,就可以直接刪除;發現當前路徑是文件夾,則遞歸調用方法,進入文件夾內部刪除裡面的文件內容。
總而言之,遞歸問題在現實學習科研中經常會遇到,這是一種解決問題的思路與方法,將大問題拆分成小問題,然後求解小問題之後回歸歸納,得出整個問題的求解結果。
本節主要介紹了遞歸的定義及基本概念,在學完本節課程之後,需要明白遞歸的基礎邏輯是什麼樣的,如何自己去設計一個遞歸演算法,在設計一個遞歸演算法時需要考慮到哪些問題,以及我們日常中常見的遞歸問題。