您的位置:首页 > 其它

hanio 塔和递规的理解。

2016-05-19 15:13 211 查看
//递规很好理解,但是初看hanoi的时候,总没有理所当然的感觉.
//那应该是对递规根本还没理解吧.仔细想了下.有点总结.

后来翻到 <<数据结构>> 112页,原来hanio的程序在这里解释了.基本和自己的思考结果一致.只是书中更简练.
书中提到的接口一致,不知道包不包括,函数可以运行的条件. 又想了想,可能真的不需要去关心函数可以运行的条件,
只要关心函数接口一致,但保证子问题和确定组合中的,确定是真的确定.也就是这个move(n,x,y),只要你n-1移走了.n 一定可以移动.
赫赫,好像稍微更清楚了一点.


//先从我们熟悉的 从1加到100.这种递规分析起把.

int main()
{
//int answer=qestion(100);
//printf("%d",answer);

qestion2(3,'x','y','z');

}

//------------------基本思路:分解问题,减低次数, 直到某次问题不再是问题,让总问题变成 [新问题]和[确定]的组合

//[总问题],[新问题],[次小问题],[最小问题(不是问题)]
//总问题分解,并减少难度
//分解为[确定]和[新问题]组合, 而新问题本质和老问题一样,并且满足老问题的解决方案的条件。
//确定[新问题]达到某个问题时,里面的问题,按照规定,是确定解。这个某个问题就是[次小问题]。
//里面的问题就是[最小问题],[最小问题],按照规定,是确定解。
//所以只要[最小问题]是确定解,依赖最小问题的次小问题([确定]和[最小问题]组合)一定有解,以至[总问题]。
//ps:([新问题],[次小问题]本质一样。只是次小问题中的问题不再是问题)

//总问题 1+2+3+...+100= ?
//分解并降低难度,总问题分解为
//    [1+2+3+...99]  + [100]
//    [新问题]       + [确定]
//    总问题的目的是累加,基本没有条件,新问题不存在条件缺失。
//到达 1+2这个问题时候,1+2是次小问题,而里面的问题1,不再是问题。1是最小问题。
int qestion(int n)
{
int answer=0;
if(n>1)
{
answer=n+qestion(n-1);//问题分解,减低难度 分解为 [确定] +[问题]
}

//    (2==n)//次小问题。  因为[新问题],[次小问题]本质一样,只是方便确定最小问题而已,注释掉。
//    {
//        answer=2+qestion(1);//qestion(1) 是最小问题,按照常识:1+question(1-1),是确定解为1。
//    }

if(1==n)//最小问题。
{
answer=1;//1+question(1-1) 按规定是1。直接写确定,终止递规。
}
return answer;
}

//总问题 从x移动n块盘到y。用z中转。
//分解并降低难度,总问题分解为
//   [从x移动n-1快盘到z,用y中转]  +[从x移动n到y]  +  [从z移动n-1快盘到y,x中转]
//   [新问题]                      + [确定]        +  [新问题]。
//   总问题的条件是,y和z是空柱子,第一个新问题,y,z都空满足同样条件,第二个新问题x空柱子。y柱子有第n盘。但根据游戏规则。n最大,y可以看作空柱子。
//   之后所有的新问题都满足条件。因为n-i块在柱子中间跳来跳去的时候,3个柱子存留的盘是>=n-i+1的,可以看作 空柱子。
//到达 n=2,只有2个盘的时候,发现这个次小问题 [从x移动2-1快盘到z,用y中转]  +[从x移动n到y]  +  [从z移动2-1快盘到y,x中转]
//   里面的所有问题都不在是问题,因为n-1,变成了2-1.
//   [从x移动2-1快盘到z,用y中转]。原来需要中转的问题变成了,移动1块盘的问题了。移动1块不再是 问题了。

void qestion2(int n,char x,char y,char z)
{

if(n>1)//问题分解,减低难度.分解为 [问题] +[确定] +[问题]
{
qestion2(n-1,x,z,y);
move(n,x,y);
qestion2(n-1,z,y,x);
}

//    (2==n)
//    {
//        ////次小问题。因为 qestion2(2-1,x,z,y),不是问题了。看看他的意思,移动一块盘,从x到z。v做中转,一块盘不需要中专了,这不是问题。
//        qestion2(2-1,x,z,y);//所以 qestion2(2-1,x,z,y)。当n等于1的时候,由问题改为确定方案move(1,x,z);
//        move(2,x,y);//
//        qestion2(2-1,z,y,x);//move(1,z,y)
//    }

if(1==n)
{
move(1,x,y);//question2(1,x,y,z),按常识,移动一块,相当于move(1,x,y),直接确定,终止递规。。
}
}

void move(int n,char x,char y)
{
printf("[%d]f:%c->%c\n",n,x,y);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: