栈的案例分析1——Hanoi塔(汉诺塔)递归问题

什么是递归?

简单来说递归就是一个程序调用自己本身的一种方法。就比如说你现在在看电视,电视里的人也在看电视......再比如说高中数学常见的一种分段函数f(x)=\left\{\begin{matrix} 2, x=0; & \\ 8-f(x-1),x>0& \end{matrix}\right.

n阶Hanoi塔问题

【问题描述】

假设有 3 个分别命名为 A、B、C 的塔座,在塔座A上插有n(假设这里 n=3)个直径大小各不相同、由小到大,编号为 1,2,...,n (n=3) 的圆盘,如上图。现要求将塔座 A 上的圆盘全部移至塔座 C 上,并仍然同样的顺序叠排,圆盘移动的时候必须遵循以下规则:

  1. 每次只能移动一个圆盘;
  2. 圆盘可以插在A、B、C中的任意一个塔座上;
  3. 任何时候都不能将一个较大的圆盘压在较小的圆盘之上。

 假设塔座 A 上最初的圆盘总数为 n 个。

(1) n = 1 的时候,直接将编号为 1 的圆盘从塔座 A 移至塔座 C 上;

(2) n > 1 (假设这里 n = 3)的时候,将执行以下三步:

        ① 用塔座 C 做为过渡,将塔座 A 上的 ( n - 1) 即 2 个圆盘移到塔座 B 上;(这里用到了递归!!)

        ② 将塔座 A 上最后一个圆盘直接移到塔座 C 上;

         用塔座 A 做为过渡,将塔座 B 上的 ( n - 1) 即 2 个圆盘移到塔座 C 上。(这里也用到了递归!!)

【算法描述】

1、定义move(A, n, C),意思就是,将编号为 n 的圆盘从塔座 A 移到塔座 C 上,同时定义一个初值为 0 的全局变量 m,以此来对移动进行计数:

int m = 0;
void move(char A, int n, char C)
{
    cout << ++m << ", " << n << ", " << A << ", " << C << ", " << endl;
}

2、 如果 n = 1,则直接将编号为 1 的圆盘从塔座 A 移至塔座 C 上,递归结束。

      否则:定义一个Hanoi函数,即 Hanoi(n, A, B, C),意思就是,将塔座A上的n个圆盘按规则移到塔座C上,塔座B作为辅助,再如上①②③所述。(!!注意这里的A, B, C是一个代表,并非一定是指A, B, C这三个圆盘)

void Hanoi(int n, char A, char B, char C)
{
    if(n == 1)
        move(A, 1, C);    //将编号为 1 的圆盘从塔座A移到塔座C
    else
    {
        Hanoi(n - 1, A, C, B);    //将塔座A上编号为 1 至 n-1 的圆盘移到塔座B上(C为辅助)
        move(A, n, C);            //将编号为 n 二栋圆盘从塔座A移到塔座C
        Hanoi(n - 1, B, A, C);    //将塔座B上编号为 1 至 n-1 的圆盘移到塔座C上(A为辅助)
    }
}

 

总体代码实现

//汉洛塔Hanoi问题 
#include <stdio.h>
#include <iostream>
using namespace std;

int m = 0;
void move(char A, int n, char C)
{ 
	cout << ++m << ", " << n << ", " << A << ", " << C <<endl;
	printf("");	
} 
void Hanoi(int n, char A, char B, char C)
{
	if(n == 1)
		move(A, 1, C);
	else
	{
		Hanoi(n - 1, A, C, B);
		move(A, n, C);
		Hanoi(n - 1, B, A, C);
	}
}
int main()
{
	Hanoi(3, 'a', 'b', 'c');
	return 0;
}

 运行结果如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值