fun函数的作用先理解:
如果传来的X/2>0,调用自身,但是传入的是X/2,而后面的printf("%d ",x); 要等前面的调用结束后再执行,所以6进来,6/2=3>0,调用自己,传入3,3/2=1>0,继续调用自己,传入1/2,1/2/2=1/4=0(只能是整数)不继续调用自己,执行printf("%d ",x),这次输出的是1,之后外层还有3和6
/ 重命名注释版 /
#include <stdioh>
#include <stdlibh>
enum Bool { False, True };
int cnt; / 排列计数 /
int perm; / 当前试验的排列 /
enum Bool valid; / 标记某个数字是否用过 /
/ 其实就是穷举n^n种有重复数字的排列,从中挑出无重复数字的排列,算法效率不高。
调用try1(n, digit)表示接着当前的排列,先试填数字digit。注意同一数先填后填会造成不同的排列。
当valid数组全部为True,即各位都没有填数字的时候,就是从某个数开始填。
当找到一个无重复的数输出后,由于多层递归逐层返回,恰好也把所有的位都置回可填。
/
void try1(int n, int digit) / digit是试验要填入的数字 /
{
int cur; / 当前试验的数位 /
for (cur = 0; cur < n; ++cur) / 逐位试填 /
{
if (valid[cur] == True) { / current位未填 /
perm[cur] = digit; / 填数 /
valid[cur] = False; / current位已填,在下面的递归中不能再填 /
if (digit == n) { / 试出一个无重复的数字 /
int k;
cnt++; / 计数 /
for(k = 0; k < n; ++k) / 输出 /
printf("%d", perm[k]);
putchar('\n');
}
else
try1(n, digit + 1); / 递归试验下一个数字 /
valid[cur] = True; / 当前位试填完,取出,可在下一轮填。注意是在递归返回后执行 /
}
}
}
int main()
{
int n, i;
printf("input n = "); / n是位数 /
scanf("%d", &n);
/ 开两个动态数组 /
perm = (int) malloc(n sizeof(int));
valid = (Bool) malloc(n sizeof(enum Bool));
if (perm == NULL || valid == NULL) exit(1);
for (i = 0; i < n; ++i) / 初始化为全部数位可用 /
valid[i] = True;
try1(n, 1); / 一开始试填1 /
printf("cnt = %d\n", cnt);
return 0;
}
使用unsigned是习惯。
只要能确定不会出现负值的整型变量,都可以定义为unsigned int型变量,这跟数字的大小无关,实际上unsigned int能比int记录的数字要大。当然你也可以使用int型。
你好,我不是很明白你的意思,其实,所有的计算机语言,都要向汇编,然后最后的二进制代码来执行……你是这个意思?因为我们看到的计算机功能越来越强大,但是归根到底,计算机最基础的零件就是电路板,它只能执行通电和断电的 *** 作
望采纳
标个记号准备上传对大神的源码分析。好了,我分析了上楼大神的代码实现,具体参考他的代码,分享下。注:可以看看《算法精解》Kyle Loudon著 或者《数据结构》 主编 安训国 他们说的堆栈原理。
#include <stdioh>
char dg(char instr, char outstr, char outstr2)
{
if (instr == 0)
{
outstr = 0;
return outstr2;
}
(outstr + 1) = instr;
outstr = dg(instr + 1, outstr + 2, outstr2);
/ 下两句一直不执行,直到outstr = dg(instr + 5, outstr + 10, outstr2)返回后才执行,其后不断执行后三句!/
outstr = instr - 32;
return outstr + 2;
}
int main()
{
char buf[50];
dg("aybdx", buf, buf);
puts(buf);
return 0;
}
确实,初学C的时候,汉诺塔的递归看起来确实是比较神奇的程序。
其中主要就在hanoi 这个递归函数,传的参数里面有一个n 代表是几层递归。
如果n=1 代表只有一个,move(one,three); 就是把第一个移到第三个就行了。否则
第一个柱子上有n个(n>1) 要移到第三个。需要把上面的n-1个移到第二个,最下面的一个移到第三个,再把第二个柱子上的n-1个移到第三个。 要这三个步骤。
其中,第一个,和第三个步骤,和本身其实是一样的。
就是把n-1个移到第二个,注意hanoi的参数
/ 定义hanoi函数,将n个盘从one座借助two座,移到three座 /
two 即第二个参数,这是表示用来借助的
就假设n=2 吧 hanoi(2,'A','B','C'); 变成了
hanoi(1,A,C,B); //这个代表A座上有一块,需要借助C座,移到B座
A--->C
hanoi(1,B,A,C); //这个代表B座上有一块,需要借助A座,移到C座
最后会输出
A-->B
A-->C
B-->C
假设n=3 hanoi(3,'A','B','C');
hanoi(2,A,C,B); //这个代表A座上有两块,需要借助C座,移到B座
A--->C
hanoi(2,B,A,C); //这个代表B座上有两块,需要借助A座,移到C座
A座上有两块,需要借助C座,移到B座 会输出
A-->C
A-->B
C-->B
B座上有两块,需要借助A座,移到C座 会输出
B-->A
B-->C
A-->C
分析过程:
根据递归函数分析:
p(w) = p(w-1) w p(w-1)
有
p(3) = p(2) 3 p(2)
p(2) = p(1) 2 p(1)
p(1) = p(0) 1 p(0)
由于p(0)不会输出任何字符,故
p(2) = p(0) 1 p(0) 2 p(0) 1 p(0)
= 1 2 1
p(3) = p(2) 3 p(2)
= 1 2 1 3 1 2 1
以上就是关于C程序解释步骤,望老师指点!全部的内容,包括:C程序解释步骤,望老师指点!、请高手分析一下此递归程序的算法思想!、c语言递归程序问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)