遞歸演算法詳解
⑴ 簡單的方法分辨枚舉演算法,排序演算法,遞歸演算法,解析演算法
枚舉就是一個一個數據試過去,看那個是對的
排序就是把數據按從大到小或從小到大排序
遞歸就是過程調用過程
指用的數學表達式,並通過表達式的計算來實現問題求解
⑵ 求漢諾塔C遞歸演算法詳細解答
Hanoi塔問題, 演算法分析如下,設A上有n個盤子。
如果n=1,則將圓盤從A直接移動到C。
如果n=2,則:
(1)將A上的n-1(等於1)個圓盤移到B上;
(2)再將A上的一個圓盤移到C上;
(3)最後將B上的n-1(等於1)個圓盤移到C上。
如果n=3,則:
A)將A上的n-1(等於2,令其為n`)個圓盤移到B(藉助於C),步驟如下:
(1)將A上的n`-1(等於1)個圓盤移到C上。
(2)將A上的一個圓盤移到B。
(3)將C上的n`-1(等於1)個圓盤移到B。
B)將A上的一個圓盤移到C。
C)將B上的n-1(等於2,令其為n`)個圓盤移到C(藉助A),步驟如下:
(1)將B上的n`-1(等於1)個圓盤移到A。
(2)將B上的一個盤子移到C。
(3)將A上的n`-1(等於1)個圓盤移到C。到此,完成了三個圓盤的移動過程。
從上面分析可以看出,當n大於等於2時, 移動的過程可分解為三個步驟:第一步 把A上的n-1個圓盤移到B上;第二步 把A上的一個圓盤移到C上;第三步 把B上的n-1個圓盤移到C上;其中第一步和第三步是類同的。 當n=3時,第一步和第三步又分解為類同的三步,即把n`-1個圓盤從一個針移到另一個針上,這里的n`=n-1。
Hanoi塔問題中函數調用時系統所做工作
一個函數在運行期調用另一個函數時,在運行被調用函數之前,系統先完成3件事:
①將所有的實參、返回地址等信息傳遞給被調用函數保存。
②為被調用函數的局部變數分配存儲區;
③將控制轉移到被調用函數的入口。
從被調用函數返回調用函數前,系統也應完成3件事:
①保存被調用函數的結果;
②釋放被調用函數的數據區;
③依照被調用函數保存的返回地址將控制轉移到調用函數。
當有多個函數構成嵌套調用時,按照「後調用先返回」的原則(LIFO),上述函數之間的信息傳遞和控制轉移必須通過「棧」來實現,即系統將整個程序運行時所需的數據空間安排在一個棧中,每當調用一個函數時,就為其在棧頂分配一個存儲區,每當從一個函數退出時,就釋放其存儲區,因此當前運行函數的數據區必在棧頂。堆棧特點:LIFO,除非轉移或中斷,堆棧內容的存或取表現出線性表列的性質。正是如此,程序不要求跟蹤當前進入堆棧的真實單元,而只要用一個具有自動遞增或自動遞減功能的堆棧計數器,便可正確指出最後一次信息在堆棧中存放的地址。
一個遞歸函數的運行過程類型於多個函數的嵌套調用,只是調用函數和被調用函數是同一個函數。因此,和每次調用相關的一個重要的概念是遞歸函數運行的「層次」。假設調用該遞歸函數的主函數為第0層,則從主函數調用遞歸函數為進入第1層;從第i層遞歸調用本函數為進入下一層,即i+1層。反之,退出第i層遞歸應返回至上一層,即i-1層。為了保證遞歸函數正確執行,系統需設立一個「遞歸工作棧」,作為整個遞歸函數運行期間使用的數據存儲區。每一層遞歸所需信息構成一個「工作記錄」,其中包括所有實參、所有局部變數以及上一層的返回地址。每進入一層遞歸,就產生一個新的工作記錄壓入棧頂。每退出一層遞歸,就從棧頂彈出一個工作記錄,則當前執行層的工作記錄必是遞歸工作棧棧頂的工作記錄,稱這個記錄為「活動記錄」,並稱指示活動記錄的棧頂指針為「當前環境指針」。
P.S.代碼如您寫的。
⑶ 一道C語言題,求大神詳解這段代碼的功能是什麼是怎麼遞歸得到功能的
這個問題必須先從遞歸演算法mul(int a,int b)來解析,而要解析一個遞歸演算法,最好的方法就是舉例。
當a=0,b=1或a=1,b=0 return結果都是0
當a=n(n為好老轎任意一個整數),b=1,retur值都為a的值,即n
當a=3,b=1.return 3;
當a=3 b=2 return 6;
當a=3 b=3 return 9;
可得當(b>0時,return 值為a*b)
當b<0時,你會發現這個可愛的演算法會一直遞歸下去,直到你的cpu發出呻吟然後死機。
所以這個演算法的b值必須>=0,所以不難看出main中要檢測v是否含兆>=0,如果v是負的,那麼就讓v變成-v。
綜上,這個演算法就是:
當u或v等於0時,列印出數就是0;
當u!=0,v>0時,列印出數就是u*v;
當u!=0,v<0時,列印出數就是-u*v;
所以寫這個可愛的演算法的人一定是個腦抽,因為這個演算法列印出數一直都是u*v。友肆
我剛開始覺得這個演算法很有意思,然而看了五秒鍾,就被深深的欺騙了。
求好評,求安慰
⑷ 用遞歸演算法求一維整型數組的最大值。求代碼,求演算法講解
int max(int array[ ],int n)
{
if (n<=1)
return(array[0]); // 就一個數,最大值就是自已
int t=max(array+1,n-1); // 求後面 n-1個數的最大值
if (t>array[0]) // t 比第一個大,返回最大 t
return(t);
else
return(array[0]); // t小,返回array[0];
}
⑸ Java數據結構二叉樹深度遞歸調用演算法求內部演算法過程詳解
二叉樹
1
2
3
4
5
6
7
這個二叉樹的深度是3,樹的深度是最大結點所在的層,這里是3.
應該計算所有結點層數,選擇最大的那個。
根據上面的二叉樹代碼,遞歸過程是:
f
(1)=f
(2)+1
>
f
(3)
+1
?
f(2)
+
1
:
f(3)
+1
f(2)
跟f(3)計算類似上面,要計算左右結點,然後取大者
所以計算順序是f(4.left)
=
0,
f(4.right)
=
0
f
(4)
=
f(4.right)
+
1
=
1
然後計算f(5.left)
=
0,f(5.right)
=
0
f
(5)
=
f(5.right)
+
1
=1
f(2)
=
f(5)
+
1
=2
f(1.left)
計算完畢,計算f(1.right)
f(3)
跟計算f(2)的過程一樣。
得到f(3)
=
f(7)
+1
=
2
f(1)
=
f(3)
+
1
=3
12345if(depleft>depright){ return depleft+1;}else{ return depright+1;}
只有left大於right的時候採取left
+1,相等是取right
⑹ 求大神講解一下C語言漢諾塔遞歸演算法的簡易理解
一開始我接觸漢諾塔也是很不解,隨著代碼量的積累,現在很容易就看懂了,因此樓主主要還是對遞歸函數的理解不夠深刻,建議你多寫一些遞歸程序,熟練了自己就能理解。
圓盤邏輯移動過程+程序遞歸過程分析
hanoi塔問題, 演算法分析如下,設a上有n個盤子,為了便於理解我將n個盤子從上到下編號1-n,標記為盤子1,盤子2......盤子n。
如果n=1,則將「 圓盤1 」 從 a 直接移動到 c。
如果n=2,則:
(1)將a上的n-1(等於1)個圓盤移到b上,也就是把盤1移動到b上;
(2)再將a上 「盤2」 移到c上;
(3)最後將b上的n-1(等於1)個圓盤移到c上,也就是第(1)步中放在b上的盤1移動到c上。
注意:在這里由於超過了1個盤子,因此不能直接把盤子從a移動到c上,要藉助b,那
么 hanoi(n,one,two,three)的含義就是由n個盤子,從one移動到three,如果n>2
那麼就進行遞歸,如果n=1,那麼就直接移動。
具體流程:
hanoi(2,a,b,c);由於2>1因此進入了遞歸的環節中。
<1>執行hanoi(1,a,c,b):這里就是剛才的步驟(1),代表藉助c柱子,將a柱子上的 1個圓盤(盤1)移動到b柱子,其實由於是n=1,此時c柱子並沒被用到,而是直接移動了。
<2>執行hanoi(1,a,b,c):這是步驟(2),藉助b柱子,將a柱子上的一個圓盤(盤2)移動到c柱子上。這里由於也是n=1,也並沒有真正藉助b柱子,直接移動的。
<3>執行hanoi(1,b,a,c):這是步驟(3),將b上的一個盤子(盤1)移動到c
函數中由於每次調用hanoi的n值都是1,那麼都不會進入遞歸中,都是直接執行了mov移動函數。
如果n=3,則:(倒著想會想明白)移動的倒數第二部,必然是下面的情況
(1)將a上的n`-1(等於2)個圓盤移到c上,也就是將盤1、盤2 此時都在b柱子上,只有這樣才能移動最下面的盤子(盤3)。那麼由於現在我們先忽略的最大的盤子(盤3),那麼我們現在的目標就是,將兩個盤子(盤1、盤2)從a柱子上,藉助c柱 子,移動到b柱子上來,這個過程是上面n=2的時候的移動過程,n=2的移動過程是「2 個盤子,從柱子a,藉助柱子b,移動到柱子c」。現在是「2個盤子,從柱子a,藉助柱子 c,移動到柱子b上」。因此移動過程直接調用n=2的移動過程就能實現。
(2)將a上的一個圓盤(盤3)移到c。
(3)到這一步,由於已經將最大的盤子(盤3)移動到了目的地,此時無論後面怎麼移動都不需要在用到最大的那個盤子(盤3),我們就先忽略他,剩下的目標就是將b上面的n-1個盤子(盤1、盤2)移動到c上,由於a上沒有盤子了,此時要完成上面的目標,就要藉助a盤子。最終達到的目標就是將b上的2個盤子,藉助a移動到c上,這個過程就是當n=2時分析的過程了,僅僅是最開始的柱子(b柱子)和被藉助的柱子(a柱子)不同了。所以直接調用n=2時候的過程就能股實現了。
具體執行過程:
hanoi(3,a,b,c);由於3>1因此進入了遞歸的環節中。
<1>執行hanoi(2,a,c,b):這里代表剛才的步驟(1),將兩個盤子(盤1、盤2)從a移動到b,中間藉助c。根據n=2的分析過程,必然是能夠達到我們的目的。
<2>執行hanoi(1,a,b,c):現在a上只有一個盤子(盤3),直接移動到c上面即可。
<3>執行hanoi(2,b,a,c):此時對應步驟(3),剩下的目標就是將b上的兩個盤子,藉助a移動到c上。那麼同樣根據n=2的移動過程,必然能達到目的。
最終實現了3個盤子從a,藉助b移動到了c。
⑺ VBA高手解析這一段遞歸組合演算法看不懂
Subzuhe(x%,z%,sr$,ggAsByte)'x新加的數字序號,z原有的數字總和,sr算式,gg原有個數
Ifz+arr(x,1)=hAndgg=g-1Then'和與個數都符合
k=k+1
arr1(k,1)=sr&arr(x,1)&"="&h
ExitSub
EndIf
Ifx<UBound(arr)Andz<hThen'沒到最後一個數且和還不足
Ifz+arr(x,1)<hThen'和不足'本行疑似有誤,改為Ifgg<g-1Then應省時
zuhex+1,z+arr(x,1),sr&arr(x,1)&"+",gg+1'增加一個數
EndIf
zuhex+1,z,sr,gg'取下一個數
EndIf
EndSub
⑻ 求漢諾塔遞歸全過程的演算法詳解圖,記得一定要是圖釋哦!!!
圖解是什麼意思呀。
這個演算法 那麼簡單沒必要搞得那麼復雜吧。
an = an-1 + 1;
你明白這個等式的意義嗎?
這個等式已經包含了遞歸演算法的全部含義。
an 表示 n個數的和,an-1 表示n-1個數的和 ,an = an-1 + 1;表示n個數的和可以通過n-1個數的和來求的。
上述說明哪些情況可以使用遞歸呢?
那就是:已知前一個步驟可以求得後一個步驟的結果的情況,並且前一個步驟和後一個步驟是有規律過度的。
比如漢諾塔問題:
移n個盤是已移n-1個盤為條件的,兩者的盯李襲共同點是移盤。所以可以用f(n)表示移n個盤,f(n-1)表示移n-1個盤,那麼移n個盤和移n-1個盤有什麼關系呢?
這就需要預先分析問題才能得出具體的關系
在這個問題中,把n個盤從a移到c需要三個步驟來完成。
1.n-1個盤從a移到b
2 1個盤從a移到c
3 n-1個盤從b移到c
已知n-1個盤從a移到b是可行的,為什麼?
因為移1個盤是可行,那麼移2個盤也是可行,移 3個盤是已移2個盤為條件的,所以移3個盤也是可行的,所以擾中移n個 盤是可行的。
所以根據已知條件可以解得:
設f(n, a, b,c) 表示 把n個盤從a移到c 藉助b --------------------------這里很關鍵,這是搞懂遞歸的關鍵關鍵。
那麼把n-1個盤從a移到b 藉助c 怎樣表示呢?
很明顯是:f(n-1, a, c,b)
那麼把1個盤從a移到c怎樣表示呢?
很明顯是:f(1, a, b,c)
那麼把n-1個盤從b移到c 藉助a 怎樣表示呢?
很明顯是:f(n-1, b, a,c)
所以f(n, a, b,c) = ( f(n-1, a,c,b) , f(1, a, b,c), f(n-1, b,a,c))
這和等差等比數列一個原理。
沒有什麼 特別的。
記住是問題有這樣遞推關系才可以使用這種方法。
如果要你計算1+2+8+22 的結果 你就不能使用遞歸。
因為該問題的後一步驟與前一步驟不具有規律性,所以已知前一個步驟並不能求的後一個步驟的值
1+2+3+4 ...+
這個問題就可以使用遞歸
原因你懂了吧。
至於爬樓梯問題,無限級分類 問題等一些遞歸問題,那不過時小菜一碟。
一句話:後一步驟依賴前一步驟並且二者聯系具有凱兄規律性,運用遞歸必然成功。
⑼ C語言問題,求詳解!!!有分!
這個是一個遞歸演算法,fun函數不斷的調用自身,最開始k=5,於是調用fun(4),但是fun(5)還沒執行完,fun(4)里繼續調用fun(3),直到fun(0)時,直接輸出0,然後函數返回上層,兆睜禪即fun(1),而fun(1)已經執行完if語句,直接輸出1,同理,函數不斷返早卜回上層,最上層的函數是fun(5),所以直到輸出5後,整段函數執行完族塵畢
⑽ 遞歸演算法 求詳解 拜託了大神們
結果:銀斗9131824
步驟如下:
1、調用caicit(9, 6),由於9>6,所以本次調用 mn = caicit(7, 5) + 6
2、調用caicit(7, 5),由於7>5,所以本次調用 mn = caicit(5, 4) + 5
3、調用caicit(5, 4),由於5>4,所以本次核枝調用 mn = caicit(3, 3) + 4
4、調用caicit(3, 3),由於3=3,所以本次調用 mn = 3*3 = 9,然後輸出mn即輸出9。
5、改搏敏返回繼續執行caicit(5, 4),mn = caicit(3, 3) + 4 = 9 + 4 = 13,輸出mn即輸出13。
6、返回繼續執行caicit(7, 5),mn = caicit(5, 4) + 5 = 13 + 5 = 18,輸出mn即輸出18。
7、返回繼續執行caicit(9, 6),mn = caicit(7, 5) + 6 = 18 + 6 = 24,輸出mn即輸出24。
由於printf沒有輸出換行,所以輸出結果為9131824。