典型递归求解之汉诺塔问题,c++实现

19 篇文章 0 订阅
11 篇文章 0 订阅

典型递归求解之汉诺塔问题,c++实现

问题分析

汉诺塔问题是典型的递归问题,

  1. 假设有n个盘要移动,n>0;A、B、C分别为三个柱子,A是原始柱子(有盘),B是间接柱子,C是目标柱子
  2. 将n个盘从A移动到C,最终结果一定是,将n-1个盘移动到B,然后第n个盘移动到C
  3. 此时,A上没有盘,B上有n-1个盘,C上有一个盘n
  4. 有3可知,此时要做的是将B上的n-1个盘移动到C上,A是间接柱子
  5. 此时问题的状态回到第一步的,只是原始柱子从A变成了B,
  6. 重复到n==0即没有盘在A、B柱子上,算法结束。

实现


// # 3. n > 3的情况:
// 	 	3.1 A作为起始点,将最底部的n号盘移动到C前需要将前面的n-1个盘子移动到间点B,移动完毕后,n-1个盘子在B上,最大得盘在C上, 
// 		3.2 因此,目前状态是B是起点,A是间接点,将最底部的n-1号盘移动到C上,需要将前面的n-2个盘子移动到间接点A上,
//		3.3 目前状态是A是起点,B是间接点,盘子个数是n-2个,状态回到3.1步骤,重复3.1步骤,直到剩下一个直接放到C,算法结束

#include<iostream>
using namespace std;

struct Node
{
	int data;
	char flag; 
	Node *next;    //在队列中的下标 
};


class Hnoi {
	private:
		Node *A;
		Node *B;
		Node *C;
		int n;
		int num;
	public:
		Hnoi(int n);
		// start起点柱子,middle过度柱子(间接柱子),dest(目标柱子),n(最大盘号) 
		void move(Node* start, Node* middle, Node* dest, int n); 
		void start();
};

Hnoi::Hnoi(int n) {
	this->n = n;
	// 定义A、B、C三个栈结构 
	this->A = new Node;
	this->A->data = 0;
	this->A->flag = 'A';
	this->B = new Node;
	this->B->data = 0;
	this->B->flag = 'B';
	this->C = new Node;
	this->C->data = 0;
	this->C->flag = 'C';
}
// 移动函数(核心)
// start起点柱子,middle过度柱子(间接柱子),dest(目标柱子),n(最大盘号) 
void Hnoi::move(Node* start, Node* middle, Node* dest, int n) {
if (n > 0) {
	// 将n-1个移动到midlle间接柱子 
		this->move(start, dest, middle, n-1);
		this->num++;
		// 将n移动到dest目标柱子,输出移动结果
		cout<<this->num<<"从"<<start->flag<<"移动到"<<dest->flag<<endl;
		// 然后,状态变为n-1个盘子在middle柱子上,start柱子是空,因此,以middle为起点,start为间接点,将n-1号盘搬到dest上 
		this->move(middle, start, dest, n-1);
}
} 
void Hnoi::start() {
	this->num = 0;
	this->move(this->A, this->B, this->C, this->n);
}

int main() {
	int n = 1;
	Hnoi hnoi(3);
	hnoi.start();
	return 0;
}

总结

个人总结:递归分析的解法主要是如何去划分解法相同的子问题,不要去思考实际,而是要用一个概括的方式去想象,更容易得出解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值