采用递归和非递归方法求解汉诺塔问题

来源:互联网 发布:中信银行网络贷款 编辑:程序博客网 时间:2024/06/05 11:14
递归:



#include<stdio.h>
void move(int n, int x, int y){
        printf("the %dth plate from %c to %c\n",n,x+65,y+65);
}
void hanoi(int n, int A, int B, int C){
        if(n==1)
            move(n,A,C);
        else{
            hanoi(n-1,A,C,B);
            move(n,A,C);
            hanoi(n-1,B,A,C);
        }
}
int main()
{
    int n;
    printf("Assuming the top plate is the first plate\nplease input the number of plate : ");
    scanf("%d",&n);
    hanoi(n,0,1,2);
}


非递归:#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
void Hanoi1(int n,char a,char b,char c)
{
 if (n==1)
  printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
    else
 {
  Hanoi1(n-1,a,c,b);
  printf("\t将第%d个盘片从%c移动到%c\n",n,a,c);
  Hanoi1(n-1,b,a,c);
 }
}

typedef struct
{ int n;
 char x,y,z;
 bool flag;
} ElemType;
typedef struct
{ ElemType data[MaxSize];
 int top;
} StackType;

void InitStack(StackType *&s)   //初始化栈
{ s=(StackType *)malloc(sizeof(StackType));
 s->top=-1;
}
void DestroyStack(StackType *&s)  //销毁栈
{
 free(s);
}
bool StackEmpty(StackType *s)   //判断栈是否为空
{
 return(s->top==-1);
}
bool Push(StackType *&s,ElemType e)  //进栈
{ if (s->top==MaxSize-1)
  return false;
 s->top++;
 s->data[s->top]=e;
 return true;
}
bool Pop(StackType *&s,ElemType &e)  //出栈
{ if (s->top==-1)
  return false;
 e=s->data[s->top];
 s->top--;
 return true;
}
bool GetTop(StackType *s,ElemType &e)  //取栈顶元素
{ if (s->top==-1)
  return false;
 e=s->data[s->top];
 return true;
}
//----------------------------------------------------
void Hanoi2(int n, char x, char y, char z)
{ StackType *st;       //定义顺序栈指针
 ElemType e,e1,e2,e3;
 if (n<=0) return;      //参数错误时直接返回
 InitStack(st);       //初始化栈
 e.n=n; e.x=x; e.y=y; e.z=z; e.flag=false;
 Push(st,e);        //元素e进栈
 while (!StackEmpty(st))     //栈不空循环
 { Pop(st,e);       //出栈元素e
  if (e.flag==false)     //当不能直接移动盘片时
  {
   e1.n=e.n-1; e1.x=e.y; e1.y=e.x; e1.z=e.z;
   if (e1.n==1)     //只有一个盘片时可直接移动
    e1.flag=true;
   else       //有一个以上盘片时不能直接移动
    e1.flag=false;
   Push(st,e1);     //处理Hanoi(n-1,y,x,z)步骤
   e2.n=e.n; e2.x=e.x; e2.y=e.y; e2.z=e.z; e2.flag=true;
   Push(st,e2);     //处理move(n,x,z)步骤
   e3.n=e.n-1; e3.x=e.x; e3.y=e.z; e3.z=e.y;
   if (e3.n==1)     //只有一个盘片时可直接移动
    e3.flag=true;
   else
    e3.flag=false;    //有一个以上盘片时不能直接移动
   Push(st,e3);     //处理Hanoi(n-1,x,z,y)步骤
  }
  else        //当可以直接移动时
   printf("\t将第%d个盘片从%c移动到%c\n",e.n,e.x,e.z);
 }
 DestroyStack(st);      //销毁栈
}

int main()
{
 int n=3;
 printf("递归算法:%d个盘片移动过程:\n",n);
 Hanoi1(n,'X','Y','Z');
 printf("非递归算法:%d个盘片移动过程:\n",n);
 Hanoi2(n,'X','Y','Z');
 return 1;
}

原创粉丝点击