漢諾塔遞歸算法拙見

逛C++吧的時候看到一個人說看不懂漢諾塔遞歸算法,我去玩了下發現就是小時候學習機上的一個遊戲啊,那時候覺得相當有難度,4個就弄不出來了尷尬

之後仔細分析了一下,發現還挺有意思的。


先看看大致的步驟:

1個盤

1       a       c

 

2個盤

1      a       b

2       a       c

1       b       c

 

3個盤

1       a       c

2       a       b

1       c       b

3       a       c

1       b       a

2       b       c

1       a       c

 

4個盤

1       a       b

2       a       c

1       b       c

3       a       b

1       c       a

2       c       b

1       a       b

4       a       c

1       b       c

2       b       a

1       c       a

3       b       c

1       a       b

2       a       c

1       b       c

說明:編號爲


a爲左柱子,b爲中間柱子,c爲右柱子

目標是把所有盤移動到c位置,具體規則我就不細說了~


文字難以理解,我就多多上圖吧


分析:

電腦的計算力和記憶力超羣,但是智商低的可以,所以它只能看到事物表面,我們只需要告訴它有兩個盤的時候該怎麼做


那麼現在有4個盤,我們可以:

把1-3看成是一個盤,並且記住這個操作,那麼現在只有3,4兩個盤,電腦就知道該怎麼做了:

但是在進行第一步將3移動到中間柱子的時候,我們還需要進去,就像做夢中夢一樣,現在變成了:

目標變成了將3之上的所有盤移動到中間柱子,當然,在把2移動到借用位置的時候,我們還要進去......

以下省略XXX字,我們跳到最後一個

當只有最後一個的時候,我們就直接移動到目標位置咯(注意是目標位置,不是最右的柱子,每一步的目標都會改變,所以我們得根據上一層函數的指示移動),然後跳出

以下再省略XXX字......


在經過不斷進入和不斷出去之後(所以說電腦的記憶力超羣),我們所有的盤就都移動到最終目標了,下面上代碼:

#include <iostream>
using namespace std;

void move(int num,int loc_now,int loc_next,int loc_aim);
void move_cout(int num,int loc_now,int loc_next);

#define LOC_A		1	//初始位置
#define LOC_B		2	//借用位置
#define LOC_AIM		3	//目標位置
//每個位置的具體作用還要看具體情況,也許LOC_B是目標位置,LOC_AIM是借用位置,這是個宏觀的作用

int main()
{
	int number;
	cout<<"please input number"<<endl;
	cin>>number;
	move(number,LOC_A,LOC_B,LOC_AIM);

	return 0;
}

/******************************************************
int num:此盤的編號
int loc_now:此盤現在所在的位置
int loc_use:將借用此位置移動到目標位置
int loc_aim:目標位置
*******************************************************/
void move(int num,int loc_now,int loc_use,int loc_aim)
{
	if(num==1)//如果只剩最後一個,直接移動到目標位置
	{
		move_cout(num,loc_now,loc_aim);
	}
	else
	{
		move(num-1,loc_now,loc_aim,loc_use);//先把除了最下面那個盤移動到借用位置

		move_cout(num,loc_now,loc_aim);//把最下面的盤移動到目標位置

		move(num-1,loc_use,loc_now,loc_aim);//再把除了最下面那個盤移動到目標位置
	}
}

/******************************************************
int num:此盤的編號
int loc_now:此盤現在所在的位置
int loc_next:將要移動到的位置
*******************************************************/
void move_cout(int num,int loc_now,int loc_next)
{
	cout<<"num-"<<num<<" move from LOC_:"<<loc_now<<" to LOC_:"<<loc_next<<endl;
}



沒想到代碼這麼短,我們看下運行結果:





		move(num-1,LOC_B,LOC_A,LOC_AIM);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章