分治算法案例一:汉诺塔

汉诺塔

实验内容

  1. 设a, b, c是3个塔座:开始时,塔座a上有n个自上而下、由小到大地叠在一起圆盘,各圆盘从小到大编号为1, 2, …, n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置,移动圆盘时遵守以下移动规则:

  2. 规则1:每次只能移动1个圆盘;

  3. 规则2:不允许将较大的圆盘压在较小的圆盘之上;

  4. 规则3:在满足移动规则1和2的前提下,可将圆盘移至a, b, c中任一塔座上。

(1) 算法设计思路
分治算法案例一:汉诺塔_第1张图片假设a为初始塔座,b为临时放置点,c为目标塔座。可将圆盘1、2、3看作是一个整体,记为A,圆盘4记为B。所以可以
            1.先将A移动到塔座b。
            2.将B移动至塔座c。
            3.将A移动至塔座c。
            整个操作过程就完成了。
细分:

  1. 当只有一个圆盘时,直接将圆盘移动到目标塔座。(作为基值条件)
  2. 当不止一个圆盘时,要把上面的n-1个盘子,借助塔座c,将n-1个圆盘移动至临时塔座b。
  3. 最后只剩下一个最大的圆盘时,就将此圆盘移动到目标塔座c。
  4. 此时,塔座b有n-1个圆盘,再借助塔座a,将n-1个圆盘移动至目标塔座c。

(2).算法实现功能
                     算法:hanoi(a, b, c,n)
                     输入:圆盘数目:int n
                     输出:圆盘移动到目标塔座的步骤
                     S1: if n==1 then
                     S2: move(a,c)
                     S3: return
                     S4: end if
                     S5: hanoi(a,c,b,n-1)
                     S6: move(a,c)
                     S7: hanoi(b,a,c,n-1)

(3)实现代码

import java.util.Scanner;
public class MyHanoi {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		char a = 'a';
		char b = 'b';
		char c = 'c';
		int n = in.nextInt();
		hanoi(a,b,c,n);
	}

	private static void hanoi(char a, char b, char c, int n) {
		//当n = 1时,即塔座只有一个圆盘,直接将此圆盘移动到目标塔座。
		if(n == 1){
			System.out.println("圆盘"+n+" "+a+"---->"+c);
			return;
		}
		//当塔座的圆盘数量>1时,需要借助塔座c,将上面的n-1个圆盘移动到塔座b
		hanoi(a,c,b,n-1);
		//只剩下一个最大的圆盘,故将最底下的圆盘移动到目标塔座
		System.out.println("圆盘"+n+" "+a+"---->"+c);
		//将n-1个圆盘借助塔座a,移动到目标塔座c
		hanoi(b,a,c,n-1);
	}
}

(4)时间复杂度分析
将(n-1)个圆盘借助a移动到b需要T(n-1)步,将最大的圆盘移动到c需要1步,再将(n-1)个圆盘从b移动到c需要T(n-1)步。故递推公式:
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
式子两边相加,可得
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(算法设计)