漢諾塔遞迴與非遞迴演算法
阿新 • • 發佈:2019-01-06
1. 基本遞迴演算法:
原文:https://blog.csdn.net/hehe5229/article/details/60874167
#include<stdio.h> #include<stdlib.h> int count=0; void move(char getone, char putone) { count++; printf("%c-->%c\n", getone, putone); } void hanoit(int n, char a, char b, char c) { if(n == 1){ move(a, c); } else { hanoit(n - 1, a, c, b); move(a, c); hanoit(n - 1, b, a, c); } } int main() { int m=5; /*"%d", &m);*/ hanoit(m, 'A', 'B', 'C'); printf("move times is(T^n-1):%d\n", count); printf("end\n"); /*system("pause"); */ return 0; }
可以使用線上編譯器檢視結果:https://tool.lu/coderunner/
2. 非遞迴演算法
演算法來源:《圖解演算法》
根據規律來提取出演算法,為了討論方便,把三根柱子編號0-2,0為起始柱子:
規律:
#include <stdio.h> /*#include <math.h>*/ int count=0; // 求a^n次方 int poww(int a, int n){ int i, count=1; if( n==0 ) return 1; for (i=0; i<n; i++) count=count*a; return count; } // 列印輸出結果 void printff(int a,int b,int c){ char tag1,tag2; count++; switch(b){ case 0: tag1='A'; break; case 1: tag1='B'; break; case 2: tag1='C'; break; } switch(c){ case 0: tag2='A'; break; case 1: tag2='B'; break; case 2: tag2='C'; break; } printf("move %d from %c to %c \n", a,tag1,tag2); } //非遞迴演算法 int hanota(int num) { int max_times; int i,k,j; int flag; int s1,s2,s3,s=0; //記錄每個盤子位置 int site[100]={0}; //判斷輸入的盤子個數是奇數還是偶數 if(num%2 == 0) flag=1; else flag=0; //求出需要搬動盤子的最大值 max_times=poww(2, num)-1; //根據規律搬動盤子 for (i=1; i <= max_times; i++){ //根據規律求出當前步數需要挪動那個盤子 for(j=num-1; j>=0; j--){ int temp; temp=poww(2,j); if(i%temp == 0 && i >= temp ) break; } //printf("*****k=%d********\n", j+1); k=j+1; //根據規律挪動盤子 if(flag){ if(k%2 != 0){ printf("move1 %d from %d to %d \n", k,site[k],(site[k]+1)%3); printff(k,site[k],(site[k]+1)%3); s=(s+1)%3; site[k]=(site[k]+1)%3; } else{ printf("move2 %d from %d to %d \n",k,site[k],abs((site[k]-1+3)%3)); printff(k,site[k],abs((site[k]-1+3)%3)); s=abs((s-1+3)%3); site[k]=abs((site[k]-1+3)%3); } } else{ if(k%2 == 0){ printf("move3 %d from %d to %d \n", k,site[k],(site[k]+1)%3); printff(k,site[k],(site[k]+1)%3); s=(s+1)%3; site[k]=(site[k]+1)%3; } else{ printf("move4 %d from %d to %d \n",k,site[k],abs((site[k]-1+3)%3)); printff(k,site[k],abs((site[k]-1+3)%3)); s=abs((s-1+3)%3); site[k]=abs((site[k]-1+3)%3); } } } } int main () { hanota(6); printf("count =%d\n", count); return 0; }