汉诺塔算法c++源代码(递归与非递归)[转]
算法介绍:
其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看)。后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子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)操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动金片:
如3阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C
汉诺塔问题也是程序设计中的经典递归问题,下面我们将给出递归和非递归的不同实现源代码。
●汉诺塔算法的递归实现C++源代码
#include <fstream>
#include <iostream>
using namespace std;
ofstream fout( "out.txt" );
void Move(int n,char x,char y)
{
fout<<"把"<<n<<"号从"<<x<<"挪动到"<<y<<endl;
}
void Hannoi(int n,char a,char b,char c)
{
if(n==1)
Move(1,a,c);
else
{
Hannoi(n-1,a,c,b);
Move(n,a,c);
Hannoi(n-1,b,a,c);
}
}
int main()
{
fout<<"以下是7层汉诺塔的解法:"<<endl;
Hannoi(7,'a','b','c');
fout.close();
cout<<"输出完毕!"<<endl;
return 0;
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
●汉诺塔算法的递归实现C源代码
#include<stdio.h>
void hanoi(int n,char A,char B,char C)
{
if(n==1)
{
printf("Move disk %d from %c to %c\n",n,A,C);
}
else
{
hanoi(n-1,A,C,B);
printf("Move disk %d from %c to %c\n",n,A,C);
hanoi(n-1,B,A,C);
}
}
void main()
{
int n;
printf("请输入数字n以解决n阶汉诺塔问题:\n");
scanf("%d",&n);
hanoi(n,'A','B','C');
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
●汉诺塔算法的非递归实现C++源代码
#include <iostream>
using namespace std;
//圆盘的个数最多为64
const int MAX = 64;
//用来表示每根柱子的信息
struct st{
int s[MAX]; //柱子上的圆盘存储情况
int top; //栈顶,用来最上面的圆盘
char name; //柱子的名字,可以是A,B,C中的一个
int Top() //取栈顶元素
{
return s[top];
}
int Pop() //出栈
{
return s[top--];
}
void Push(int x) //入栈
{
s[++top] = x;
}
} ;
long Pow(int x, int y); //计算x^y
void Creat(st ta[], int n); //给结构数组设置初值
void Hannuota(st ta[], long max); //移动汉诺塔的主要函数
int main(void)
{
int n;
cin >> n; //输入圆盘的个数
st ta[3]; //三根柱子的信息用结构数组存储
Creat(ta, n); //给结构数组设置初值
long max = Pow(2, n) - 1; //动的次数应等于2^n - 1
Hannuota(ta, max); //移动汉诺塔的主要函数
system("pause");
return 0;
}
void Creat(st ta[], int n)
{
ta[0].name = 'A';
ta[0].top = n-1;
//把所有的圆盘按从大到小的顺序放在柱子A上
for (int i=0; i<n; i++)
ta[0].s[i] = n - i;
//柱子B,C上开始没有没有圆盘
ta[1].top = ta[2].top = 0;
for (int i=0; i<n; i++)
ta[1].s[i] = ta[2].s[i] = 0;
//若n为偶数,按顺时针方向依次摆放 A B C
if ( n%2 == 0)
{
ta[1].name = 'B';
ta[2].name = 'C';
}
else //若n为奇数,按顺时针方向依次摆放 A C B
{
ta[1].name = 'C';
ta[2].name = 'B';
}
}
long Pow(int x, int y)
{
long sum = 1;
for (int i = 0; i < y; i++)
sum *= x;
return sum;
}
void Hannuota(st ta[], long max)
{
int k = 0; //累计移动的次数
int i = 0;
int ch;
while (k < max)
{
//按顺时针方向把圆盘1从现在的柱子移动到下一根柱子
ch = ta[i%3].Pop();
ta[(i+1)%3].Push(ch);
cout << ++k << ": " << "Move disk " << ch << " from "
<< ta[i%3].name <<" to " << ta[(i+1)%3].name << endl;
i++;
//把另外两根柱子上可以移动的圆盘移动到新的柱子上
if (k < max)
{
//把非空柱子上的圆盘移动到空柱子上,当两根柱子都为空时,移动较小的圆盘
if (ta[(i+1)%3].Top() == 0 || ta[(i-1)%3].Top() > 0
&& ta[(i+1)%3].Top() > ta[(i-1)%3].Top())
{
ch = ta[(i-1)%3].Pop();
ta[(i+1)%3].Push(ch);
cout << ++k << ": " << "Move disk " << ch << " from "
<< ta[(i-1)%3].name << " to " << ta[(i+1)%3].name << endl;
}
else
{
ch = ta[(i+1)%3].Pop();
ta[(i-1)%3].Push(ch);
cout << ++k << ": " << "Move disk " << ch << " from "
<< ta[(i+1)%3].name << " to " << ta[(i-1)%3].name << endl;
}
}
}
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
汉诺塔算法c++源代码(递归与非递归)[转]的更多相关文章
- 汉诺塔算法的递归与非递归的C以及C++源代码
汉诺塔(又称河内塔)问题其实是印度的一个古老的传说. 开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一 个小, ...
- java利用递归实现汉诺塔算法
package 汉诺塔; //引入Scanner包,用于用户输入 import java.util.Scanner; public class 汉诺塔算法 { public static void m ...
- java实现汉诺塔算法
package com.ywx.count; import java.util.Scanner; /** * @author Vashon * date:20150410 * * 题目:汉诺塔算法(本 ...
- 汉诺塔算法详解之C++
汉诺塔: 有三根杆子A,B,C.A杆上有N个(N>1)穿孔圆环,盘的尺寸由下到上依次变小.要求按下列规则将所有圆盘移至C杆: 每次只能移动一个圆盘: 大盘不能叠在小盘上面. 提示:可将圆盘临时置 ...
- Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法-un
ylbtech-Java-Runoob-高级教程-实例-方法:03. Java 实例 – 汉诺塔算法 1.返回顶部 1. Java 实例 - 汉诺塔算法 Java 实例 汉诺塔(又称河内塔)问题是源 ...
- python实现汉诺塔算法
汉诺塔 算法分析 1.步骤1:如果是一个盘子,直接将a柱子上的盘子从a移动到c 否则 2.步骤2:先将A柱子上的n-1个盘子借助C移动到B(图1) 已知函数形参为hanoi(n,a,b,c),这里调用 ...
- Java汉诺塔算法
汉诺塔问题[又称河内塔]是印度的一个古老的传说. 据传开天辟地之神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把 ...
- python 递归实现汉诺塔算法
def move(n,a,b,c): if (n == 1): print ( "第 ", n ," 步: 将盘子由 " ,a ," 移动到 &quo ...
- 如何用Go语言实现汉诺塔算法
package main import ( "fmt" ) func print(n int,x rune,y rune)(){ fmt.Printf("moving d ...
随机推荐
- 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)
题链 http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩 ...
- JS获取所有LI中第三个<SPAN>
- python re 正则提取中文
需求: 提取文本中的中文和数字字母(大小写都要),即相当于删除所有标点符号. 其中new是原字符串 news = re.findall(r'[\u4e00-\u9fa5a-zA-Z0-9]',new)
- zoj 2722 Head-to-Head Match(两两比赛)
Head-to-Head Match Time Limit: 2 Seconds Memory Limit: 65536 KB Our school is planning to hold ...
- zoj 1251 Box of Bricks
Box of Bricks Time Limit: 2 Seconds Memory Limit: 65536 KB Little Bob likes playing with his bo ...
- NYOJ595乱七八糟好坑的水题~~
乱七八糟 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 一天,PIAOYI查看班级成绩时发现各种乱七八糟的数据,有点晕--但是他现在非常想知道排名情况,你能帮帮他吗?为 ...
- 理工个人积分赛最后一场(FZU)G - 五子棋,坑爹的大水题~~
Problem 1490 五子棋 Time Limit: 1000 mSec Memory Limit : 32768 KB Problem Description 五子棋是起源于中国古代的传统黑白 ...
- 以太坊和IPFS如何存储数据
如何将JSON文件存储在IPFS上,并使用Oraclize访问智能合约中的数据呢? 以太坊是一个成熟的区块链,使开发人员能够创建智能合约,在区块链上执行的程序可以由交易触发.人们经常将区块链称为数据库 ...
- [POJ3041] Asteroids(最小点覆盖-匈牙利算法)
传送门 题意: 给一个N*N的矩阵,有些格子有障碍,要求我们消除这些障碍,问每次消除一行或一列的障碍,最少要几次. 解析: 把每一行与每一列当做二分图两边的点. 某格子有障碍,则对应行与列连边. ...
- 【字符串+BFS】Problem 7. James Bond
https://www.bnuoj.com/v3/external/gym/101241.pdf [题意] 给定n个字符串,大小写敏感 定义一个操作:选择任意m个串首尾相连组成一个新串 问是否存在一个 ...