借漢諾塔理解棧與遞歸

我們先說,在一個函數中,調用另一個函數。

首先,要意識到,函數中的代碼和平常所寫代碼一樣,也都是要執行完的,只有執行完代碼,或者遇到return,才會停止。

那么,我們在函數中調用函數,執行完了,就會重新回到本函數中,繼續向下執行,直到結束。

在執行其它函數時,本函數相當于中斷了,不執行了。那我們重新回來的時候,要從剛才暫停的地方開始,繼續執行,這期間,所有現場信息都要原封不動,就相當于時間暫停了一樣,什么都不能改變,這樣才能做到程序的準確。

所以,通常,在執行另一個函數之前,電腦會將現場信息壓入一個系統棧,為被調用的函數分配存儲區,然后開始執行被調函數。執行完畢后,保存計算結果,釋放被調函數的空間,按照被調函數里保存的返回地址,返回到原函數。

那什么是遞歸函數呢?

就是多個函數嵌套調用。不同的是,這些函數是同一個函數,只是參數可能不同,甚至參數也一樣,只是存儲空間不同。

每一層遞歸所需信息構成一個棧,每一塊內存儲著所有實在參數,所有局部變量,上一層的返回地址,等等一切現場信息。每執行完就彈出。

遞歸函數有著廣泛應用,主要適合可以把自身分化成一樣的子問題的問題。比如漢諾塔。

?

漢諾塔:漢諾塔(又稱河內塔)問題是源于印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

思路:函數(n,a,b,c)含義是把n個盤子從a柱子搬到c柱子的方法

一個盤子,直接搬過去。

多個盤子,我們把n-1個盤子都移動到另一個柱子上,把最大的搬過去然后把剩下的搬過去。

?

def hanoi(n, a, b, c):if n == 1:print(a, '-->', c)else:hanoi(n - 1, a, c, b)print(a, '-->', c)hanoi(n - 1, b, a, c)
# 調用
hanoi(3, 'A', 'B', 'C')

結果:

A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C

我們的棧:

第一次:

我們把hanoi(3, 'A', 'B', 'C')存了起來,調用了hanoi(3-1, 'A', 'C', 'B'),現在棧里壓入了3, 'A', 'B', 'C',還有函數執行到的位置等現場信息。然后執行hanoi(3-1, 'A', 'C', 'B'),發現要調用hanoi(3-1-1, 'A', 'B', 'C'),我們又把3-1, 'A', 'C', 'B'等信息壓入了棧,現在棧是這樣的:

棧頭

2, 'A', 'C', 'B'

3, 'A', 'B', 'C'

棧尾

?

然后執行hanoi(3-1-1, 'A', 'B', 'C'),發現n=1了,打印了第一條A --> C,然后釋放掉了hanoi(3-1-1, 'A', 'B', 'C')的空間,并通過記錄的返址回到了hanoi(3-1, 'A', 'C', 'B'),然后執行打印語句A --> B,然后發現要調用hanoi(3-1-1, 'C', 'A', 'B'),此時棧又成了:

2, 'A', 'C', 'B'
3, 'A', 'B', 'C'

調用hanoi(1, 'A', 'C', 'B')發現可以直接打印,C --> B。

然后我們又回到了2, 'A', 'C', 'B'這里。發現整個函數執行完了,那就彈出吧。這時棧是這樣的:

3, 'A', 'B', 'C'

只有這一個。

我們繼續執行這個函數的代碼,發現

def hanoi(n, a, b, c):
? ? if n == 1:
? ? ? ? print(a, '-->', c)
? ? else:
? ? ? ? hanoi(n - 1, a, c, b)//執行到了這里
? ? ? ? print(a, '-->', c)
? ? ? ? hanoi(n - 1, b, a, c)

?

那我們就繼續執行,發現要打印A --> C

然后繼續,發現要調用? ? ? ? hanoi(n - 1, b, a, c),那我們繼續把現場信息壓棧,繼續執行就好了。

?

遞歸就是把大問題分解成小問題進而求解。

具體執行就是通過系統的棧來實現返回原函數的功能。

?

多色漢諾塔問題:

?

奇數號圓盤著藍色,偶數號圓盤著紅色,如圖所示。現要求將塔座A 上的這一疊圓盤移到塔座B 上,并仍按同樣順序疊置。在移動圓盤時應遵守以下移動規則:

規則(1):每次只能移動1 個圓盤;
規則(2):任何時刻都不允許將較大的圓盤壓在較小的圓盤之上;
規則(3):任何時刻都不允許將同色圓盤疊在一起;
?

其實雙色的漢諾塔就是和無色的漢諾塔算法類似,通過推理可知,無色漢諾塔的移動規則在雙色漢諾塔這里的移動規則并沒有違反。

這里說明第一種就可以了:Hanoi(n-1,A,C,B);

在移動過程中,塔座上的最低圓盤的編號與n-1具有相同奇偶性,塔座b上的最低圓盤的編號與n-1具有不相同的奇偶性,從而塔座上的最低圓盤的編號與n具有相同的奇偶性,塔座上c最低圓盤的編號與n具有不同的奇偶性;
?

所以把打印操作換成兩個打印即可

?

總:因為遞歸可能會有重復子問題的出現。

就算寫的很好,無重復子問題,也會因為來回調用、返回函數,而速度較慢。所以,有能力的可以改為迭代或動態規劃等方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445538.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445538.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445538.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單迷宮問題

迷宮實驗是取自心理學的一個古典實驗。在該實驗中,把一只老鼠從一個無頂大盒子的門放入,在盒子中設置了許多墻,對行進方向形成了多處阻擋。盒子僅有一個出口,在出口處放置一塊奶酪,吸引老鼠在迷宮中尋找道路以到達出口…

qt超強繪圖控件qwt - 安裝及配置

qwt是一個基于LGPL版權協議的開源項目, 可生成各種統計圖。它為具有技術專業背景的程序提供GUI組件和一組實用類,其目標是以基于2D方式的窗體部件來顯示數據, 數據源以數值,數組或一組浮點數等方式提供, 輸出方式可以是…

BFPRT

在一大堆數中求其前k大或前k小的問題,簡稱TOP-K問題。而目前解決TOP-K問題最有效的算法即是BFPRT算法,其又稱為中位數的中位數算法,該算法由Blum、Floyd、Pratt、Rivest、Tarjan提出,最壞時間復雜度為O(n)O(n)。 讀者要會快速排序…

180°舵機的使用步驟

一.步驟 1.首先查看舵機的運行參數,包括工作的電壓和電流,轉1(60)需要的脈寬是多少。 2.根據舵機提供的參數,算出需要的PWM的周期和脈寬的范圍。 3.通過單片機或者其他數字電路產生相應的PWM波,便可以驅…

Qt開源項目

圖像處理: Krita digikam inkscape 編輯器: LiteIDE QDevelper KDeveloper Monkey Studio TeXstudio 繪圖: ZeGrapher QtiPlot qcustomplot QWT HotShots Inkscape 三維建模: QCAD FreeCAD OpenModelica LibreCAD 音樂&#xff1a…

使用Python作為計算器

數值 1.python支持基本的數學運算符,而且應用python你可以像寫數學公式那樣簡單明了。 eg: >>> 2 2 4 >>> 50 - 5*6 20 >>> (50 - 5*6) / 4 5.0 >>> 8 / 5 # division always returns a floating point number 1.6 2.除法…

java整體打印二叉樹

一個調的很好的打印二叉樹的代碼。 用空格和^v來表示節點之間的關系。 效果是這樣: Binary Tree: v7v v6v ^5^ H4H …

前綴樹

是一種哈希樹的變種。典型應用是用于統計,排序和保存大量的字符串(但不僅限于字符串),所以經常被搜索引擎系統用于文本詞頻統計。它的優點是:利用字符串的公共前綴來減少查詢時間,最大限度地減少無謂的字符…

學習4層板設計

今天是第一天嘗試設計四層PCB板,以前只畫過雙層板,所以今天花了好多時間來熟悉多層板的設計方法,現在做一下整理,也方便其他同胞少走彎路~~~我用的軟件是Altium Designer 6(AD6)步驟如下: 1、隨…

PCB設計的基本步驟

一.方案的設計 1.與客戶溝通,確定電路的功能和相關設計指標(如:電源,功耗等)。 2.畫出項目的硬件功能框圖。 3.設計出多種方案,并對多種方案進行對比,最終選出最合適的方案。 4.根據上述所…

堆應用例題三連

一個數據流中,隨時可以取得中位數。 題目描述:有一個源源不斷地吐出整數的數據流,假設你有足夠的空間來保存吐出的數。請設計一個名叫MedianHolder的結構,MedianHolder可以隨時取得之前吐出所有樹的中位數。 要求: 1…

HistCite 的使用方法

摘要 讀文獻自然要讀精品,在面對一個陌生領域,如何才能以最快速度定位精品文獻呢?本文將詳細介紹 HistCite 的使用方法,結合 Web of Science 和 Endnote ,演示如何在幾個小時之內,對某個陌生領域的文獻進行…

數組基操三連(2)

轉圈打印矩陣 題目: 給定一個整型矩陣matrix,請按照轉圈的方式打印它。例如:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,打印結果為:1,2,3,4,5,12,16,15,14,13,9,5,6,7,11,10 要求: 額外空間復雜度為O(1&a…

數據結構課上筆記7

介紹棧和隊列基本概念和用法。 設輸入序列1、2、3、4,則下述序列中( )不可能是出棧序列。【中科院中國科技大學2005】 A. 1、2、3、4 B. 4、 3、2、1 C. 1、3、4、2 D.4、1、2、3 選…

ROC曲線與AUC值

ROC曲線與AUC值 1.概述AUC(Area Under roc Curve)是一種用來度量分類模型好壞的一個標準。這樣的標準其實有很多,例如:大約10年前在machine learning文獻中一統天下的標準:分類精度;在信息檢索(IR)領域中常…

設置SSH免密碼自動登錄(使用別名)

每次登錄服務器都要寫一大串的用戶名(username服務器地址)和登錄密碼十分的繁瑣,所以本文就告訴大家如何通過修改配置文件,達到只需要輸入:ssh jack(你起的別名)就可以一鍵登錄到服務器中。 1.創建公鑰(相當…

串的定長表示

思想和代碼都不難&#xff0c;和線性表也差不多&#xff0c;串本來就是數據受限的線性表。 串連接&#xff1a; #include <stdio.h> #include <string.h> //串的定長順序存儲表示 #define MAXSTRLEN 255 //用戶可在255以內定義最大串長 typedef unsigned cha…

周志華《Machine Learning》 學習筆記系列(1)--緒論

機器學習致力于研究如何通過計算手段&#xff0c;利用經驗來改善系統本身的性能&#xff0c;在計算機系統中&#xff0c;“經驗”通常是以“數據”形式存在的&#xff0c;所以&#xff0c;機器學習的主要內容是關于在計算機上從數據中產生“模型”的算法&#xff0c;即學習算法…

輕松理解牛頓迭代法且用其求平方根

牛頓迭代法概述 牛頓迭代法&#xff08;Newton’s method&#xff09;又稱為牛頓-拉弗森方法&#xff08;Newton-Raphson method&#xff09;&#xff0c;它是牛頓在17世紀提出的一種在實數域和復數域上近似求解方程的方法。 牛頓迭代公式 設rrr是f(x)0f(x)0f(x)0的根&#…

map+DP leetcode446

如果數字序列由至少三個元素組成并且任何兩個連續元素之間的差異相同&#xff0c;則稱為算術序列。 例如&#xff0c;這些是算術序列&#xff1a; 1&#xff0c;3&#xff0c;5&#xff0c;7&#xff0c;9 7&#xff0c;7,7&#xff0c;7 3&#xff0c;-1&#xff0c;-5&am…