Hanoi塔问题

设A,B,C是三个塔座。开始时,在塔座A上有一叠共n个圆盘,这些圆盘自上而下,由大到小地叠在一起,各圆盘从小到大编号为1,2,。。。,n。现要求将塔座A上的这一叠圆盘移到塔座B上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则:

规则(1)每次只能移动一个圆盘;

规则(2)任何时刻都不允许将较大的圆盘压在较小的圆盘之上;

规则(3)在满足移动规则(1)和(2)的前提下,可将圆盘移至A,B, C中任一塔座上。

       这个问题有一个简单的解法。假设塔座A、B、C排列成一个三角形,A——>B——>C——>A构成一顺时针循环。在移动圆盘的过程中,若是奇数次移动,则将最小的圆盘移到顺时针方向的下一塔座上;若是偶数次移动,则保持最小的圆盘不动。而其他两个塔座之间,将较小的圆盘移到另一塔座上去。

       上述算法简洁明确,可以证明它是正确的。下面用递归技术来解决同一问题。

当n=1时,问题比较简单。此时,只要将编号为1的圆盘从塔座A直接移至塔座B上即可。

当n>1时,需要利用塔座C作为辅助塔座。此时设法将n-1个较小的圆盘依照移动规则从塔座A移至塔座C,然后,将剩下的最大圆盘从塔座A移至塔座B,最后,再设法将n-1个较小的圆盘依照移动规则从塔座C移至塔座B。

这样一来,n个圆盘的移动问题就可分解为两次n-1个圆盘的移动问题,我们又可以递归地用上述方法来做。

void Hanoi(int n,int A,int B,int C)
{
      if(n>0)
      {
            Hanoi(n-1,A,C,B);
            Move(n,A,B);
            Hanoi(n-1,C,B,A);
     }
}


 

其中,Hanoi(n,A,B,C)表示将塔座A上自下而上,由大到小叠在一起的n个圆盘依移动规则移至塔座B上并仍按同样顺序叠排。在移动过程中,以塔座C作为辅助塔座。

            Move(n,A,B)表示将塔座A上编号为n的圆盘移至塔座B上。

 

Hanoi塔问题的非递归算法描述

void hanoi(int n)
{
    int top[3]={0,0,0};
    int **tower;
    Make2DArrary(tower,n+1,3);//生成二维数组
    int b,bb,x,y,min=0;
    for(int i=0;i<=n;i++)
    {
        tower[i][0]=n-i+1;
        tower[i][1]=n+1;
        tower[i][2]=n+1;
    }
    top[0]=n;b=odd(n);bb=1;
    while(top[1]<n)
    {
        if(bb)
        {
            x=min;
            if(b)
                y=(x+1)%3;
            else 
                y=(x+2)%3;
            min=y;bb=0;
        }
        else
        {
            x=(min+1)%3;y=(min+2)%3;bb=1;
            if(tower[top[x]][x]>tower[top[y]][y])
                Swap(x,y);
        }
        move(tower[top[x]][x],x+1,y+1);
        tower[top[y]+1][y]=tower[top[x]][x];
        top[x]--;top[y]++;
    }
}

下面对非递归算法进行模拟

Hanoi塔问题_第1张图片

下面用数数归纳法证明递归算法和非递归算法产生相同的移动序列。

当n=1和n=2时容易直接验证。设当k<=n-1时,递归算法 和非递归算法产生完全相同的移动序列。考察k=n的情形。

将移动分为顺序时针移动(C)、逆时针移动(CC)和非最小圆盘塔座间的移动(O)三种情况。

当n为奇数时,顺时针非递归算法产生的移动序列为C,O,C,O,...,C;逆时针非递归算法产生的移动序列为CC,O,CC,O,...,CC。

当n为偶数时,顺时针非递归算法产生的移动序列为CC,O,CC,O,...,CC;逆时针非递归算法产生的移动序列为C,O,C,O,...,C。

(1)当n为奇数时,顺时针递归算法hanoi(n,A,B,C)产生的移动序列为

hanoi(n-1,A,B,C)产生的移动序列,O,hanoi(n-1,C,B,A)产生的移动序列。

其中,hanoi(n-1,A,C,B)和hanoi(n-1,C,B,A)均为偶数圆盘逆时针移动问题。由数学归纳法知,它们产生的移动序列均为C,O,C,O,...,C。因此,hanoi(n,A,B,C)产生的移动序列为C,O,C,O,...,C。

(2)当n为偶数时,顺时针递归算法hanoi(n,A,B,C)产生的移动序列为

hanoi(n-1,A,C,B)产生的移动序列,O,hanoi(n-1,C,B,A)产生的移动序列

其中,hanoi(n-1,A,B,C)和hanoi(n-1,C,B,A)均为奇数圆盘逆时针移动问题。由数学归纳法知,它们产生的移动序列均为CC,O,CC,O,...,CC。因此,hanoi(n,A,B,C)产生的移动序列为CC,O,CC,O,...,CC。

当n为奇数和偶数时的逆时针递归算法也类似。

由数学归纳法可知,递归算法和非递归算法产生相同的移动序列。


你可能感兴趣的:(c,算法)