帶你理解C語(yǔ)言中的漢諾塔公式
漢諾塔公式
漢諾塔問題在數(shù)學(xué)層面的公式:
不用說,你看到這個(gè)公式一定一臉懵逼,我現(xiàn)在來講解這個(gè)公式的作用。
先來回想一下大象放冰箱要幾步,三步吧,打開冰箱,放進(jìn)去,關(guān)上門就行了,我們先不要去思考一些細(xì)碎的步驟,將一個(gè)復(fù)雜的問題先簡(jiǎn)單化,再慢慢去分析。
那漢諾塔問題也是同樣的簡(jiǎn)單三步:(假設(shè)有n個(gè)盤子)
一、把最大的盤子留在A柱,然后將其他的盤子全放在B柱。
二、把最大的盤子放到C柱。
三、然后將B柱上的所有盤子放到C柱。
這就是漢諾塔的流程,漢諾塔的精髓就是上面三句話。
n層漢諾塔有(2^n-1)次移動(dòng),來將盤子全部從A盤到C盤.
C語(yǔ)言遞歸公式
相應(yīng)我們可以寫出對(duì)應(yīng)的C語(yǔ)言遞歸公式:(n就是盤子的個(gè)數(shù),xyz就是柱子的名字)
相信你肯定有很多疑問,我們現(xiàn)在先來舉幾個(gè)例子再解釋問題吧。
一個(gè)盤子就不說了,因?yàn)樽畲蟮谋P子就是他,所以他直接就去C盤了。
兩層漢諾塔
共三步:把最大盤上面的全部放到B,然后最大盤去C,再把剩余的盤全部放到C就行了。
這是兩個(gè)盤,共移動(dòng)三次就移動(dòng)完了,那三個(gè)盤呢?
三層漢諾塔
把全部過程堪稱一個(gè)整體,最大盤上面的所有盤全部看成一個(gè)整體,我們也只用執(zhí)行三個(gè)步驟,我們要利用把大事化小的觀點(diǎn),不要一上來就思考具體是怎么移動(dòng)的,這樣看不清問題的本質(zhì)。
我們?cè)賮砭唧w分析三步具體要怎么移動(dòng).
第一步中,我們要移動(dòng)三次,分別是A->C、是A->B、C->B這就是一大次完整的移動(dòng),在這一步中,我們套用了上一次的漢諾塔公式進(jìn)行使用,這就是漢諾塔的難點(diǎn),接下來我給大家看個(gè)圖,希望大家能理解,(n是層數(shù),X,Y,Z則是函數(shù)參數(shù))
漢諾塔的內(nèi)部其實(shí)就像一個(gè)金字塔一樣,其實(shí)每一次調(diào)用自己,就是按照上面所說精髓的公式調(diào)用自己,讓自己的參數(shù)發(fā)生了變化。我希望大家能夠自己去照著畫一下流程,
第二步:將A到C,這就是將上圖的第二步那寫上第四次移動(dòng):A->C。
第三步,將B柱上的全部盤子借助A放到C
第七步完成后就會(huì)發(fā)現(xiàn)沒有要執(zhí)行的語(yǔ)句了,漢諾塔函數(shù)就結(jié)束返回到main函數(shù)了,自此求解漢諾塔函數(shù)的步驟就完成了。
好的,這樣,我們移動(dòng)三層漢諾塔的過程的就完成了,三次漢諾塔完成就算是解決了這個(gè)問題,因?yàn)榧词贡P子再多也就是一樣的公式套用而已,明白兩層和三層漢諾塔的運(yùn)行原理就可以了,再多層的塔也是相同的流程。不難發(fā)現(xiàn),遞歸就是讓數(shù)學(xué)公式在C語(yǔ)言中體現(xiàn)了出來,讓問題變的十分”簡(jiǎn)單“。
剩下就是了程序的主函數(shù)部分了,這個(gè)問題的主函數(shù)就很簡(jiǎn)單,主函數(shù)只用傳來盤子的數(shù)量和三個(gè)柱子的名字就行了;代碼如下
#include <stdio.h> void change (char x,char y) //打印盤子移動(dòng)軌跡的函數(shù) { printf("%c->%c\n", x, y); } void f(n, x, y, z) //漢諾塔函數(shù) { if (n == 1) { change(x, z); } else { f(n - 1, x, z, y); //公式一:將A柱最大盤外的盤子借助C柱移到B柱 change(x, z); //公式二:將A上最大盤移動(dòng)到C柱 f(n - 1, y, x, z); //公式三:將B柱上的盤借助A全部放到C柱 } } int main() { int m; scanf("%d", &m); f(m, 'A', 'B', 'C'); }
總結(jié)
到此這篇關(guān)于帶你理解C語(yǔ)言中的漢諾塔公式的文章就介紹到這了,更多相關(guān)C語(yǔ)言漢諾塔公式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c++ Protobuf解決數(shù)據(jù)傳輸瓶頸面試精講
這篇文章主要介紹了c++ Protobuf解決數(shù)據(jù)傳輸瓶頸利器面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10C語(yǔ)言實(shí)現(xiàn)時(shí)區(qū)轉(zhuǎn)換函數(shù)的實(shí)例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)時(shí)區(qū)轉(zhuǎn)換函數(shù)的實(shí)例的相關(guān)資料,這里分析需求并提供實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-08-08C++設(shè)計(jì)一個(gè)簡(jiǎn)單內(nèi)存池的全過程
利用C/C++開發(fā)大型應(yīng)用程序中,內(nèi)存的管理與分配是一個(gè)需要認(rèn)真考慮的部分,下面這篇文章主要給大家介紹了關(guān)于C++設(shè)計(jì)一個(gè)簡(jiǎn)單內(nèi)存池的全過程,需要的朋友可以參考下2021-09-09淺談Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用
這篇文章主要介紹了Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用,Glib庫(kù)在多線程編程中經(jīng)常可以用到,需要的朋友可以參考下2016-02-02C++?STL容器詳解之紅黑樹部分模擬實(shí)現(xiàn)
本文主要對(duì)紅黑樹進(jìn)行了詳細(xì)介紹,并對(duì)其核心功能進(jìn)行了模擬實(shí)現(xiàn)。文中的代碼對(duì)我們的學(xué)習(xí)或工作有一定的價(jià)值,感興趣的小伙伴可以了解一下2021-12-12C++string中的insert()插入函數(shù)詳解
這篇文章主要介紹了C++string中的insert()插入函數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03C語(yǔ)言實(shí)現(xiàn)學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02