汉诺塔递归与非递归算法

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;
}


猜你喜欢

转载自blog.csdn.net/llanlianggui/article/details/80545460