汉诺塔的非递归实现 【大杂烩】未完

本文介绍了汉诺塔问题的背景及递归解法,并探讨了C和C++中递归实现的差异。作者通过递归思路解决汉诺塔问题后,尝试使用非递归的堆栈方法进行实现,虽然遇到困难但分享了相关参考资料,鼓励读者深入理解。文章还提及了非递归解法的步骤和策略,以及C语言的链表实现代码,尽管存在错误。
摘要由CSDN通过智能技术生成

7-17 汉诺塔的非递归实现 (25分)

官方介绍:
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

这个题目在大一的时候就见过那个时候只是感觉代码挺少的,但是完全不理解。最先是在C语言课本上看到的,完全不知道这是什么东西,而且马上下课了,老师也没用讲完,后来下周一的晚上计导老师讲了这个问题,只是感觉知道这是怎么一回事了,但是和独立写出代码还差的远。
我总会逃避自己感觉困难的事情,这个过程我认为很难,从来没用写过,哪怕后来刷题的时候,我也照着书上的答案来写,自己还真没用想过这是怎么一回事,今天在数据结果这里看到了它,一定要好好的研究研究。

题目如下:

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数。

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

输入样例:

3

输出样例:

a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c

好了,看一下图解:

百度百科找的动态的图。
在这里插入图片描述
这些柱子更加形象呢!
在这里插入图片描述

所以,今天我先用递归的方式解这道题。

递归实现方法【C&C++】:

先写一下我的体会吧。
之前只是在网上看到很多人在说,C的输入和输出效率比C++要高,但是我一直不知道怎么回事,今天写这个题目的时候理解到了。同样的代码和套路,C能够通过没用问题,但是C++就会运行超时,之前还看到过加快输入和输出的方法,现在也不会,也没用必要使用,找个效率高的算法使用就行了。

C语言递归:

#include<stdio.h>
#include<stdlib.h>

void move(char a,char b) {
	printf("%c -> %c\n",a,b);
}

void hanoi(int n,char a,char b,char c) {
	if(n==1) {
		move(a,c);
		return ;
	}
	hanoi(n-1,a,c,b);
	move(a,c);
	hanoi(n-1,b,a,c);
}

int main() {
	int n;
	char a='a',b='b',c='c';
	scanf("%d",&n);
	hanoi(n,a,b,c);
	return 0;
}

C++递归:

必须要使用C语言形式的输入和输出,才不会运行超时。

#include<bits/stdc++.h>
using namespace std;

void move(char a,char b) {
	printf("%c -> %c\n",a,b);
}

void hanoi(char a,char c,char b,int n) {
	if(n==1) {
		move(a,c);
		return ;
	} else {
		hanoi(a,b,c,n-1);
		move(a,c);
		hanoi(b,c,a,n-1);
	}
}

int  main() {
	int N;
	char a='a',b='b',c='c';
	scanf("%d",&N);
	hanoi(a,c,b,N);
	return 0;
}

好了,到这里就复习完了,马上开始下一步,按照题目要求来解题。像我这种小菜鸡肯定不会写了,只能慢慢磨了。
又是一个堆栈问题。

汉诺塔的非递归实现【未完成,勿用】

我写了好久,参考了好多,但是还是不太理解,为什么人家的代码可以通过,而我的连正常的输出都做不到呢?
参考链接
有时间再改改!!!

这是一个有意思的博主。
5-17 汉诺塔的非递归实现 (25分)
可以参考一下。博主提到的原文我找到了,但是我没有受到没用启发,我还是不会写,QAQ。
一位美国学者发现一种出人意料的方法,只要轮流进行两步操作就可以了。

首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上。

根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放 A B C;

若n为奇数,按顺时针方向依次摆放 A C B。

(1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;

若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。

(2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。

即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘

这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。

(3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。

C语言链表有误代码

#include <stdio.h>
#include <stdlib.h>
#define MAX 64

typedef struct
{
	int N;
	char a;
	char b;
	char c;
} ElementType;//定义了一个基本数据类型

typedef struct
{
	ElementType data[MAX];
	int top;
} Stack; //定义了一个顺序栈

//元素入栈的操作
void Push(Stack *s,ElementType a)
{
	if(s->top==MAX)
		return ;
	else
	{
		s->top++;
		s->data[s->top]=a;
		return ;
	}
}

//元素出栈的操作
ElementType Pop(Stack *s)
{
	if(s->top==-1)
		return ;
	else
	{
		s->top--;
		return (s->data[(s->top)+1]);
	}

}

//通过栈实现非递归的方法
void hanoi(int n)
{
	ElementType p,temp;
	Stack s;
	p.N=n;
	p.a='a';
	p.b='b';
	p.c='c';
	//对p这个基本数据类型进行赋值
	s.top=-1;//顺序栈的初始化

	Push(&s,p);
	while(s.top!=-1)
	{
		p=Pop(&s);
		if(p.N==1)
		{
			printf("%c -> %c\n",p.a,p.c);//(N,a,b,c)
			return ;
		}
		else
		{
			//(N-1,b,a,c),这是第三步操作
			temp.N=p.N-1;
			temp.a=p.b;
			temp.b=p.a;
			temp.c=p.c;
			Push(&s,temp);

			//(1,a,b,c),这是第二部操作
			temp.N=1;
			temp.a=p.a;
			temp.b=p.b;
			temp.c=p.c;
			Push(&s,temp);

			//(N-1,a,c,b),这是第一步操作
			temp.N=p.N-1;
			temp.b=p.c;
			temp.c=p.b;
			temp.a=p.a;
			Push(&s,temp);

		}
	}
}

int main()
{
	int n;
	scanf("%d",&n);
	if(n<=0)
		return 0;
	else
		hanoi(n);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摆烂.MVP

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值