⑴ c語言:求解漢諾塔問題
漢諾塔問題用遞歸解決比較容易,下面代碼是我用C++寫的,你可以參考
#include <iostream>
using namespace std;
void Move(char ch1,char ch2)
{
cout<<ch1<<"------->"<<ch2<<endl;
}
void Hannuo(int n,char PA,char PB,char PC)
{
if (n==1)
{
Move(PA,PC);
return;
}
else {
Hannuo(n-1,PA,PC,PB);
Move(PA,PC);
Hannuo(n-1,PB,PA,PC);
}
}
void main()
{ int N;
cout<<"請輸入你要移動的盤子數:";
cin>>N;
Hannuo(N,'A','B','C');
}
⑵ C語言--漢諾塔程序執行步驟
這個問題你要先把遞歸搞懂才能理解的, 最好是單跟蹤執行一下, 我這里就簡單說一下吧!
hanoi(5, 'a', 'b', 'c');把5個從'a'移到'c'
這時n=5, noe='a', two='b', three='c'
因為n!=1, 執行else里的
hanoi( 4, 'a', 'c', 'b'); //把上面4個從a移到b
move( 'a', 'c'); //把第5個從a移到c
hanoi( 4, 'b', 'a', 'c'); //再把那4個從b移到c
上面的很好明白的, 再分析hanoi( 4, 'a', 'c', 'b'); //把上面4個從a移到b,也是執行else
hanoi( 3, 'a', 'b', 'c'); //把上面3個從a移到c
move( 'a', 'b'); //把第4個從a移到b
hanoi( 4, 'c', 'a', 'b'); //再把那3個從c移到b
一直到n=1才結束
⑶ 求大神講解一下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。
⑷ c語言漢諾塔.
# include <stdio.h>
void hannuota(int n,char A,char B, char C);
int main(void)
{
char ch1 = 'A';
char ch2 = 'B';
char ch3 = 'C';
int n;
printf("請輸入要移動的盤子的個數:");
scanf("%d",&n);
hannuota(n,'A','B','C');
return 0;
}
//將A柱子上的n個盤子藉助於B移動到C柱子上,
//每次移動時,必須保證大盤子在小盤子下面
//最大值不能是64
void hannuota(int n,char A,char B,char C)
{
/*
如果是1個盤子
直接將A柱子上的盤子從A移動到C
否則
先將A柱子上的n-1個盤子藉助於C從A移動到B
直接將A柱子上的盤子從A移動到C
最後將B柱子上的n-1個盤子藉助於A從B移動到C
*/
if (1 == n)
{
printf("將編號為%d的盤子從%c柱子移動到%c柱子\n",n,A,C);
}
else
{
hannuota(n-1,A,C,B);
printf("將編號為%d的盤子從%c柱子移動到%c柱子\n",n,A,C);
hannuota(n-1,B,A,C);
}
}
/*
在vc++6.0中的輸出結果:
------------------
請輸入要移動的盤子的個數:3
將編號為1的盤子從A柱子移動到C柱子
將編號為2的盤子從A柱子移動到B柱子
將編號為1的盤子從C柱子移動到B柱子
將編號為3的盤子從A柱子移動到C柱子
將編號為1的盤子從B柱子移動到A柱子
將編號為2的盤子從B柱子移動到C柱子
將編號為1的盤子從A柱子移動到C柱子
-------------------
*/
/*
供參考! 呵呵
*/
⑸ C語言中的漢諾塔問題,誰能分析給我。
反復的遞歸的調用move函數,程序很好理解,就是一個遞歸的反復執行先將n-1個盤子從x借z移到y上,然後將第n個移到z,最後將y上的n-1個盤子通過x移到z上。實際上就是漢諾塔中嵌套漢諾塔#include<stdio.h>move(int n,char x,char y,char z){ if(n==1) printf("%c-->%c\n",x,z); else { move(n-1,x,z,y); printf("%c-->%c\n",x,z); move(n-1,y,x,z); }}int main(){ int n; printf("input diskes number:\n"); scanf("%d",&n); printf("The step moving %d diskes:\n",n); move(n,'A','B','C'); getchar(); return 0;}
⑹ 用C語言編程序解決漢諾塔問題
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
int count;
void movedisk(int,char,char,char);
int _tmain(int argc, _TCHAR* argv[])
{
int n;
printf("輸入盤子的數量:");
scanf("%d",&n) ;
movedisk(n,'A','C','B');
printf("盤子數量%d的時候移動了%d次\n",n,count);
scanf("%d",&n) ;
}
void movedisk(int n,char from,char to,char tmp)
{
if(n>1)
movedisk(n-1,from,tmp,to);
printf("盤子 %d 號從柱子 %c 移動到了柱子 %c 上\n",n,from,to);
count++;
if(n>1)
movedisk(n-1,tmp,to,from);
}
⑺ 求漢諾塔c語言動畫演示程序
#include <graphics.h>
struct H
{
int data[15];/*存放每個盤的代號*/
int top;/*每個塔的具體高度*/
}num[3];/*三個塔*/
void move(char x,char y,struct H num[3]);/*移動的具體過程*/
void hanoi(char x,char y,char z,int n,struct H num[3]);/*遞歸*/
void Init(void);/*初始化*/
void Close(void);/*圖形關閉*/
int computer=1;/*自動控制與手動控制的標志*/
int speed=0;/*全局變數speed主要是演示過程的速度*/
void main(void)
{
Init();/*初始狀態*/
Close();/*圖形關閉*/
exit(0);
}
void Init(void)/*初始化*/
{
int gd=DETECT,gm;
int i,n,color;
clrscr();
printf("please input n(n<=10): ");/*輸入要演示的盤子數*/
scanf("%d",&n);
printf("Please input 1 or 2:\n1.computer 2.people\n");
scanf("%d",&i);
if(i==2)/*選擇手動控制標志為0*/
computer=0;
if(n<1||n>10)
n=10;/*越界的話n當10處理*/
if(computer)/*如果是自動控制的話輸入速度*/
{
printf("please input speed: ");/*輸入速度*/
scanf("%d",&speed);
}
initgraph(&gd,&gm,"D:\\tc");
cleardevice();
for(i=0;i<3;i++)
num[i].top=-1;/*三個地方的高度開始都為-1*/
for(i=0;i<n;i++)/*畫一開始的塔座A上的盤子*/
{
num[0].top++;/*棧的高度加1*/
num[0].data[num[0].top]=i; /*最大的盤子代號為0,依次為1,2,…n-1*/
color=num[0].data[num[0].top]+1;/*盤子的顏色代碼為棧頂盤子代號加1*/
setfillstyle(SOLID_FILL,color);
bar(100-(33-3*num[0].data[num[0].top]),400-20*i-8,100+
(33-3*num[0].data[num[0].top]),400-20*i+8); /*畫矩形*/
}
setcolor(YELLOW);
outtextxy(180,450,"any key to continue");
settextstyle(0,0,2);
outtextxy(90,420,"A"); /*塔座標志*/
outtextxy(240,420,"B");
outtextxy(390,420,"C");
getch();/*接收字元後就執行遞歸操作*/
hanoi('a','b','c',n,num);
}
void move(char x,char y,struct H num[3])/*移動的具體過程*/
{
int i;
char num1[3],num2[3];
sprintf(num1,"%c",x-32);/*將小寫變成大寫,並轉換成字元串輸出*/
sprintf(num2,"%c",y-32);
setfillstyle(SOLID_FILL,BLACK);/*把原來的地方移去塗黑*/
bar(0,0,640,60);
setcolor(RED);
outtextxy(150,30,num1);/*輸出移動過程*/
outtextxy(200,30,"--->");
outtextxy(310,30,num2);
settextstyle(0,0,2);
setfillstyle(SOLID_FILL,BLACK);/*把原來的地方移去塗黑*/
bar(100+150*(x-97)-(33-3*num[x-97].data[num[x-97].top]),
400-20*num[x-97].top-8,100+150*(x-97)+(33-3*
num[x-97].data[num[x-97].top]),400-20*num[x-97].top+8);
num[y-97].top++;/*入棧,目標點的top加1*/
num[y-97].data[num[y-97].top]=num[x-97].data[num[x-97].top];/*在目標點盤子的代號與源點盤子的代號相同*/
num[x-97].top--;/*出棧,原來地方的top減1*/
setfillstyle(SOLID_FILL,num[y-97].data[num[y-97].top]+1);/*盤子顏色代碼是棧頂盤子代號加1*/
bar(100+150*(y-97)-(33-3*num[y-97].data[num[y-97].top]),
400-20*num[y-97].top-8,100+150*(y-97)+
(33-3*num[y-97].data[num[y-97].top]),400-20*num[y-97].top+8);
if(computer)/*自動控制就用delay*/
delay(speed);/*延時函數*/
else
getch();/*手動控制的話就自己按鍵盤來控制*/
}
void hanoi(char one,char two,char three,int n,struct H num[3])/*遞歸n為盤子數,num為堆棧*/
{
if(n==1)
move(one,three,num);/*如果盤子為1,將這個盤子從塔座A移動到塔座C*/
else
{
hanoi(one,three,two,n-1,num);/*將塔座A的前n-1個盤子移到塔座B*/
move(one,three,num);/*將塔座A的第n個盤子移到塔座C*/
hanoi(two,one,three,n-1,num); /*將塔座B的n-1個盤子移到塔座C*/
}
}
void Close(void)/*圖形關閉*/
{
getch();
closegraph();
}
演示過程在TC 下進行。。嘻嘻
⑻ C語言漢諾塔程序
將以下內容全部復制到新建的源文件中:(本人自己寫的,因為你那課本上的代碼,沒解釋,書寫不規范,很難理解清楚,所以我直接新寫了一個完整的代碼,附帶詳細說明)
#include <stdio.h>
//漢諾塔x層塔從A塔整體搬到C塔,中間臨時B塔。
//x層塔是從大到小往上疊放。每次移動只能移動一層塔。並且在移動過程中必須保證小層在上邊
//藉助B塔可以將x層塔全部從A搬到C上,並且符合要求(在移動過程中大的那塊在下邊,小的那塊在上邊)
int main()
{
void tower(int x,char a,char b,char c); //聲明函數
int x=5,a='A',b='B',c='C'; //x表示有5層塔,具體要多少層自己修改這個值。abc分別表示ABC塔。
tower(x,a,b,c); //x層塔從a移動到c的全過程,主程序只有這條有效語句
return 0;
}
//以下是tower函數的定義
//參數解析:x層塔放在a上,b是中間塔,c是目標塔。即x層塔要從a搬到c上。
//此函數實現x層塔從a整體轉移到c上。以及這個過程是怎麼搬的全部過程。
void tower(int x,char a,char b,char c)
{
if(x==1)printf("將%d從%c放到%c\n",x,a,c); //只有1層塔時,直接從a搬到c上。
else //不止1層塔,則先將x-1層塔從a按照規律搬到b上,再將最後一塊從a搬到c上,最後再將b上的x-1層塔按照規律搬到c上。
{
tower(x-1,a,c,b); //先將x-1層塔從a按照規律搬到b上,注意參數b放在最後,因為放在最後的參數是准備搬過去的目標塔。
printf("將%d從%c放到%c\n",x,a,c); //將最後一塊從a搬到c上
tower(x-1,b,a,c); //最後再將b上的x-1層塔按照規律搬到c上,注意參數b放在開頭,因為x-1層是要從b上搬過去的。
}
}
⑼ C語言漢諾塔(高分提問)
其實漢諾塔就是遞歸問題,你理解了遞歸思想,自然就很容易懂,這種問題一般都作為編程語言教程的遞歸例子講解的,你其實可以仔細看看課本的.
hanio(n-1,a,c,b);// 這語句的意思是:首先將a 上面的n-1個盤通過c 移動到b ,這樣的結果是,a 只剩下最大一塊盤,然後直接移動到c就行了,所以也就有move(a,c); 之後a 為空,b 有剛才移動的n-1個盤,c 上面已經有個最大的了,如果把剩下的n-1移動到c ,就完成了,所以接著有下面的語句:
hanio(n-1,b,a,c); //這意思說,把b 上的n-1個盤通過a 移動到c,
就這樣完成遞歸,一次次執行下去,就行了.
⑽ C語言漢諾塔的問題
要看懂遞歸程序,往往應先從最簡單情況看起。
先看hanoi(1, one, two, three)的情況。這時直接將one柱上的一個盤子搬到three柱上。注意,這里one柱或three柱到底是A、B還是C並不重要,要記住的是函數第二個參數代表的柱上的一個盤被搬到第四個參數代表的柱上。為方便,將這個動作記為:
one =》three
再看hanoi(2, one, two, three)的情況。考慮到hanoi(1)的情況已經分析過了,可知這時實際上將產生三個動作,分別是:
one =》two
one =》three
two =》three
很顯然,這實際上相當於將one柱上的兩個盤直接搬到three柱上。
再看hanoi(3, one, two, three)的情況。分析
hanoi(2, one , three, two)
one =》three
hanoi(2, two, one, three)
即:先將one柱上的兩個盤搬到two柱上,再將one柱上的一個盤搬到three柱上,最後再將two柱上的兩個盤搬到three柱上。這不就等於將one柱上的三個盤直接搬到three柱上嗎?
運用歸納法可知,對任意n,
hanoi(n-1, one , three, two)
one =》three
hanoi(n-1, two, one, three)
就是先將one柱上的n-1個盤搬到two柱上,再將one柱上的一個盤搬到three柱上,最後再將two柱上的n-1個盤搬到three柱上。這就是我們所需要的結果!