棧與遞迴的實現 Hanoi塔問題等等

2022-08-29 12:24:13 字數 2020 閱讀 5628

函式中有直接或間接地呼叫自身函式的語句,這樣的函式稱為遞迴函式。遞迴函式用

得好,可簡化程式設計工作。但函式自己呼叫自己,有可能造成死迴圈。為了避免死迴圈,要

做到兩點:

(1) 降階。遞迴函式雖然呼叫自身,但並不是簡單地重複。它的實參值每次是不一樣

的。一般逐漸減小,稱為降階。如教科書式(33)的ackerman 函式,當m≠0 時,求

ack(m,n)可由ack(m-1,⋯)得到,ack()函式的第1 個引數減小了。

(2) 有出口。即在某種條件下,不再進行遞迴呼叫。仍以教科書式(33)的ackerman

函式為例,當m=0 時,ack(0,n)=n+1,終止了遞迴呼叫。所以,遞迴函式總有條件語

句。m=0 的條件是由逐漸降階形成的。如取ack(m,n)函式的實參m=-1,即使通過降階也

不會出現m=0 的情況,這就造成了死迴圈。

編譯軟體在遇到函式呼叫時,會將呼叫函式的實參、返回位址等資訊存入軟體自身所

帶的棧中,再去執行被調函式。從被調函式返回時,再將呼叫函式的資訊出棧,接著執行

呼叫函式。編譯軟體開闢的棧空間是有限的,當遞迴呼叫時,巢狀的層次往往很多,就有

可能使棧發生溢位現象,從而出現不可預料的後果。執行algo3-8.cpp 時,m、n 的取值就

不可過大。

// algo3-8.cpp 用遞迴呼叫求ackerman(m,n)的值

#includeint ack(int m,int n)

void main()

**執行結果:

/*

please input m,n:3,9

ack(3,9)=4093

press any key to continue

*/

// algo3-9.cpp 用遞迴函式求解迷宮問題(求出所有解)

#include"c1.h" // 根據《pascal程式設計》(鄭啟華編著)中的程式改編

#include"func3-1.cpp" // 定義牆元素值為0,可通過路徑為-1,通過路徑為足跡

void try(postype cur,int curstep)

,,,}; // ,移動方向,依次為東南西北

for(i=0;i<=3;i++) // 依次試探東南西北四個方向

m[next.x][next.y]=-1; // 恢復為通路,以便在另乙個方向試探另一條路

curstep--; // 足跡也減1

} }}void main()

**執行結果如下:

此迷宮從入口到出口有2 條路徑。由入口(1 行1 列足跡1)處向4 個方向試探,只有2

個方向(東、南)是通路(-1)。首先朝東繼續試探。足跡2~4 都只有1 個方向是通路,足

跡5 到達出口。輸出路徑且逐一恢復足跡為-1(通路)。恢復後的情況是除入口為1 外,迷

宮其它各點與初態相同,以便第2 條路徑(由入口向南)繼續試探。

// algo3-10.cpp hanoi塔問題,呼叫演算法3.5的程式

#includeint c=0; // 全域性變數,搬動次數

void move(char x,int n,char z)

void hanoi(int n,char x,char y,char z) // 演算法3.5

}void main()

**執行結果如下:

/*

3個塔座為a、b、c,圓盤最初在a座,借助b座移到c座。請輸入圓盤數:3

第1步: 將1號盤從a移到c

第2步: 將2號盤從a移到b

第3步: 將1號盤從c移到b

第4步: 將3號盤從a移到c

第5步: 將1號盤從b移到a

第6步: 將2號盤從b移到c

第7步: 將1號盤從a移到c

press any key to continue

*/

棧與遞迴(Hanoi塔問題)

今天上午上課時,再看了下hanoi塔的問題,其中對遞迴的分析,讓自己對遞迴呼叫有了更深一步地理解,把書上的 實現一下,然後分析其遞迴工作棧的狀態,理解了以後,會讓自己受益頗多。學習,不能只看著別人是怎麼寫的,自己就照著寫,這是非常不對的,你要分析別人為什麼這樣寫,你要懂得的是思路,而不僅僅是答案。1...

hanoi塔問題的遞迴實現

一 背景故事 二 問題描述 假設有x,y,z三座塔座。在塔座x上有n個直徑各不相同 依次從小到大的編號為1,2.n的圓盤。現要求將x座上的盤子移動到z上,移動要求如下 1 一次只能移動乙個盤子。2 盤子只能插在x,y,z的某個塔座上。3 任何時刻不能將較大的盤子壓在較小的盤子上。如何移動盤子呢?當只...

遞迴 Hanoi塔問題

題目 hanoi塔問題,遊戲規則 1 每次只能移動乙隻圓盤 2 任何時候大圓盤不能壓在小圓盤之上 3 任何時候都不允許將圓盤放在三根立軸之外的任何地方。分析 遞迴的 base case 當只有乙個圓盤的時候,直接從圓盤所在的立軸移動到目標立軸,即完成。遞迴的 recursion rule 如圖所示,...