汉诺塔递归的c语言实现(递归)

【C语言】汉诺塔问题(图文详解) C语言汉诺塔及详细图文展示 阅读详情

对于递归来讲, 汉诺塔实际是经典到不能再经典的例子了,   每个数据结构的教材对会提到.

     但是到最后只给出一段类似下面的一段代码:

 

 
  1. #include<stdio.h>

  2.  
  3. void move(int n,char a,char b,char c)

  4. {

  5. if(n==1)

  6. printf("\t%c->%c\n",a,c); //当n只有1个的时候直接从a移动到c

  7. else

  8. {

  9. move(n-1,a,c,b); //把a的n-1个盘子通过c移动到b

  10. printf("\t%c->%c\n",a,c); //把a的最后1个盘(最大的盘)移动到c

  11. move(n-1,b,a,c); //吧b上面的n-1个盘通过a移动到c

  12. }

  13. }

  14.  
  15. main()

  16. {

  17. int n;

  18. printf("请输入要移动的块数:");

  19. scanf("%d",&n);

  20. move(n,'a','b','c');

  21. }

 

 

     这段代码用来学习递归思想是足够的,  也能大概上了解到移动汉诺塔的步骤.

    

     但是我说, 这段代码没有体会出汉诺塔的本质, 也没有办法验证.

      下面我会敲出能体现出汉诺塔本质的递归代码. 并能根据输出每1个步汉诺塔的状态, 并且验证正确性.

 

 

1. 什么是汉诺塔

 下面的定义摘自维基百科:

有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

 

配图:

 

 

 

 

2. 汉诺塔的本质是3个栈

      维基的定义只简单提到了汉诺塔的规则, 但是并没有揭示它的本质.   下面我们来分析它的本质.

      1.每次只能移动1个盘:      

      也就说不能两个盘一齐移动, 必须按顺序1个1个套在柱子上,  而且只能从柱子的上方套入, 也能只能从柱子的上方取出.

      这明显就是1个先进后出的线性结构了,  因为出入口只有1个啊, 柱子的下方是不能放入和取出盘子的. 

      先进后出的线性结构就是栈了,  套入柱子和取出盘子就是对应的压栈和出栈动作.   如果读者之前没有了解过栈的话, 个人建议先去了解下栈, 然后再往下看.

 

      2. 大盘不能套在小盘上面

      代表这3个栈中, 如果不是空栈, 那么压栈的元素必须比栈顶元素小, 然后才允许压栈.   这就保证栈里面的元素是从小到大排序的.

 

      总结:  汉诺塔的本质就是3个栈,  而且压栈的元素必须比栈顶元素(如果存在)小.

 

 

3. 汉诺塔的解题思路及递归原理

 

     好, 现在开始讲解汉诺塔的解题思路.

     假如A塔有n个盘子, 大小从大(底部) 到小(顶部)排列,  B塔和C塔都是空塔.

     如下图:

好了那么到底如何把这个n个盘子移动到C塔呢?

 

 

3.1  假如n=1 也就是说A塔只有1个盘子的情况下, 直接将1个盘子移动到c塔

 

那么我们写1个函数move()

执行move(A,C) 就是把A里唯一1个盘子移动到C

当然这里先不管这个函数具体是如何实现的.

但是可看出, 这个过程是不需要借助B塔中转的.

 

 

3.2  n>1的情况分析, hanoi_m(A,B,C,n) 函数

 

但是n>1呢? 上面的move函数就行不同了, 所以我们需要1个新的函数 hanoi_m()

hanoi_m(A, B, C, n) 函数意思就是把n个盘子从A借助B移动到C.

这里也先不管这个函数是如何具体如何实现, 知道它的参数意义和目地就ok了.

 

我上篇文章讲过, 递归的条件之一就是令数据规模不断地减少, 也就是假如1个函数f(n) 是递归函数, 则必须要找出f(n) 与f(n-1)关系,  也就是说把求f(n) 转化为求f(n-1), 然后再转化为求f(n-2), 最终f(1)就是出口.

那么这里的hanoi_m(x,x,x,1) 是什么呢?  就是上面的move()函数了,  也就说出口找到了.

 

但是hanoi_m(x,x,x,n) 与 hanoi_m(x,x,x, n-1) 的关系还不知道,  这就是汉诺塔递归函数的精髓了!

下面步骤就是讲解这个n 与 n-1的关系.

 

关键的一点:  假如要将n-1个盘子放到C塔, 如果c塔是非空的话, 那么c塔的盘子都必须比n-1大, 否则按照规则是不能放入的!

所以 最大的盘子必须比 它小的所有盘子先放入C塔.  

 

1.但是如果要将最大的盘子从A塔移动到C塔,  那么C塔必须是空的, 不让放不下

2.而且最大的盘子必须在A塔的最上面, 也就是说A塔只有1个最大的盘子.

3.所以其他盘子都必须在B塔上,

 

理解好这个那么问题就不大了

 

下面是详细步骤

 

 

3.3  第一步, 将A上面的n-1个盘子借助C塔移动到B塔. hanoi(A,C,B,n-1)

这个过程用函数来表示就是hanoi_m(A,C,B,n-1)啊, 理解这一步也十分关键:

如图:

 

至于这个过程具体如何实现, 这里也不用去管, 只有1点是明确的, 只要n-1>1 那么这个过程肯定需要C塔来中转, 而且肯定可以化为求 hanoi_m(x,x,x, n-2).

假如n-1=1? 就直接move(A,B)就ok了, 这就是出口啊.

 

 

3.4  第二步, 将A上面的最后的(最大的)盘子移动到C塔 move(A,C)

  因为现在A塔了只有1个最大盘子n了啊, 所以无需借助B塔, 直接move(A,C)搞定

 

如下图:

 

注意现在还没完成哦

 

 

3.4  第三步, 将B上面的所有盘子(n-1)个盘子借助A塔移动到C塔 hanoi(B,A,C,n-1)

 

因为C塔的盘子比B塔的所有盘子都大, 所以是可以忽略掉C盘的那个最大的盘子的, 理解这个也很重要啊.

这个函数实现就是 hanoi(B,A,C,n-1)

如图:

搞掂完成了...

 

 

 

3.5  总结及伪算法:

经过上面的图解, 我们知道hanoi(n) 与hanoi(n-1)的关系了, 可以分成三步啊

伪算法就是:

 
  1. hanoi_m(A,B,C,n){

  2. if (n==0){

  3. move(A,C);

  4. }

  5. hanoi_m(A,C,B,n-1);

  6. move(A,C);

  7. hanoi_m(B,A,C,n-1);

  8. }

 

看看这个函数, 自己调用了自己, 而且规模不断在减少, 还有1个明确的出口, 标准的递归函数啊.

再看看本文开始那个函数, 是不是能理解了

 

然而 真正的代码实现没那么简单,  但是起码逻辑已经清楚了.

 

 


 

 

 

 

 

 

4. 1个静态栈(数组内核)的容器的c语言代码实现

 

     假设我们可以用类似下面的代码来定义3个栈, 和调用压栈和出栈函数, 就很方便了.

 
  1. //declare a stucks

  2. stuck A = new stuck;

  3.  
  4. //push

  5. A->push(1); //push element int "1" into the stuck

  6.  
  7. //pop

  8. int i;

  9. A->pop(&i) //pop the top element, and assign the value to variable i

  10.  

 

咋一看不是c++的代码吗?, 的确c语言不能实现面向对象的类.

但是利用c语言里的结构体和函数指针, 也可以实现类似上面代码的功能.

 

用c语言写1个静态栈容器并不是很简单, 可以说远比汉诺塔的函数复杂,  具体的代码我就不讲解了. 有兴趣的可以参考我之前的文章, 有1个动态栈(链表内核)的c语言代码例子讲解.

但是静态栈的原理远比动态栈复杂.

 

下面我只会介绍下头文件的函数, 具体当面我会作为附件, 有兴趣的可以下载:

 

 
  1. #include "bool_me.h"

  2. #ifndef __ARRSTUCK1_H_

  3. #define __ARRSTUCK1_H_

  4.  
  5. struct arrstuck1{

  6. int * pArr; //address of array (int type)

  7. int arrlen; //the maxlen of th array

  8. int top; //index of the top + 1

  9. int buttom; //index of buttom , default is 0

  10. const char * stname; //name of stuck, haha ,used to print the log to logfile

  11. int (* len)(struct arrstuck1 *); //get the length

  12. int (* TopVal)(struct arrstuck1 *); //get the top value

  13. int (* ButtomVal)(struct arrstuck1 *); //get the top value

  14. BOOL (* is_empty)(struct arrstuck1 *);

  15. BOOL (* is_full)(struct arrstuck1 *);

  16. BOOL (* push)(struct arrstuck1 *, int); //push an element to the stuck

  17. BOOL (* pop)(struct arrstuck1 *, int *); //pop the topelemnt to the stuck

  18. void (* print)(struct arrstuck1 *); //print from buttom to top

  19. void (* print_from_top)(struct arrstuck1 *); //print from top to buttom

  20. void (* clean)(struct arrstuck1 *); //remove all elements

  21. BOOL is_inited; //judge whether the arraystuck is initialed

  22. };

  23.  
  24. typedef struct arrstuck1 INT_STUCK;

  25.  
  26. //initail

  27. INT_STUCK * ast_int_new();

  28. //free

  29. BOOL ast_free(INT_STUCK *);

  30.  
  31. #endif /* __ARRSTUCK1_H_ */

 

上面就是静态栈容器 INT_STUCK(定义别名) 的头文件, 它只可以存放int类型的元素.

我们只需要关系几个关键的成员函数.

1.  push()  函数 就是压栈啦

2. pop() 函数 出栈

3. print() 打印栈里面的所有元素, 用于验证算法的正确性啦.

4. len()  栈里面元素的个数.

5. ast_int_new5.  in() 初始化函数, 不初始化没法用的.

 

其他的可以看注释了.

 

具体的函数定义请下载来看:

bool_me.h  :  定义BOOL 类型

basefuncs.h

basefuncs.c  :输出错误和日志的基本函数

arrstuck1.h

arrstuck1.c   静态栈容器

 

因为这篇文章的注意目地是分析汉诺塔的递归函数嘛..

 

 

 

5. 汉诺塔递归c语言实现

      好了, 到此为止, 准备动作做完了, 下面开始分析和编写汉诺塔的函数

 

5.1  定义单个汉诺塔类型 及 其初始化函数

     上面讲过了, 汉诺塔的本质就是栈,, 所以汉诺塔类型就是栈啦, 用typedef 函数起个别名就ok了

     利用函数指针可以为函数起别名

 

代码如下:

 
  1. typedef INT_STUCK HANOITOWER;

  2. static HANOITOWER * (* hanoi_new)() = ast_int_new;


这样就定义了1个"新"的类型  HANOITOWER,  和初始化函数 hanoi_new()

 

 

5.2  汉诺塔放盘子函数hanoi_push

实际上就是栈的压栈函数,  当然, 这里要判断入栈的值必须比栈顶小!

代码如下:

 
  1. BOOL hanoi_push(HANOITOWER * pIst, int val){

  2. if (TRUE != pIst->is_empty(pIst) && val >= pIst->TopVal(pIst)){

  3. printf("val is greater than top!\n");

  4. return FALSE;

  5. }

  6.  
  7. pIst->push(pIst, val);

  8. return TRUE;

  9. }


 

5.3  定义3个汉诺塔栈 A,B,C 并往A里面放4个盘子

有了上面的函数, 就可以初始化3个塔, 并往A塔放4个盘子了, 当然B,C塔必须是空塔(空栈)

当然放几个盘子自己定义, 建议不要放太多啦, 移动盘子动作增长速度很恐怖的. 反正我的渣机子算24个盘子要5分钟才出结果

代码如下: 

 
  1. HANOITOWER * pTa = hanoi_new();

  2. pTa->stname = "TowerA";

  3. HANOITOWER * pTb = hanoi_new();

  4. pTb->stname = "TowerB";

  5. HANOITOWER * pTc = hanoi_new();

  6. pTc->stname = "TowerC";

  7.  
  8. int i;

  9.  
  10. for (i=4; i >= 1; i--){

  11. hanoi_push(pTa, i);

  12. }

 

5.4 从非空汉诺塔取盘子函数 hanoi_pop

没错, 本质上就是出栈函数啊, 拿出栈顶元素(用于放到别的栈)

所以要接受1个 int 类型的指针参数,  用于存放和取出这个栈顶啊.

代码如下:

 
  1. BOOL hanoi_pop(HANOITOWER * pIst, int * pVal){

  2. if (TRUE == pIst->is_empty(pIst)){

  3. printf("fail to pop as the stuck is empty!\n");

  4. return FALSE;

  5. }

  6.  
  7. pIst->pop(pIst, pVal);

  8. return TRUE;

  9. }

 

5.5  把1个盘子从1个塔移动到另1个塔函数 hanoi_move

没错, 实际上我们操作汉诺塔, 不会单独地取盘子和放盘子,   而是把1个塔的顶部盘子拿出来 放到另1个塔的顶部!

所以 这个函数Hanoi_move 的参数有两个栈, T_from 和 T_to

实际上是分解上出栈和压栈函数

从T_from出栈 并获得出栈的元素(盘子), 然后把这个元素压栈到T_to中.

代码如下:

 

 
  1. BOOL hanoi_move(HANOITOWER * pIst_from, INT_STUCK * pIst_to){

  2. int val;

  3. if (TRUE == hanoi_pop(pIst_from, &val)){

  4. if (TRUE == hanoi_push(pIst_to, val)){

  5. //mark log to file

  6. sprintf(hanoi_move_str, "\nmove %d from %s to %s\n", val, pIst_from->stname, pIst_to->stname);

  7. base_log(hanoi_move_str, HANOI_OP_FILE, "a");

  8. base_log_intarr(pIst_from->stname, pIst_from->pArr, pIst_from->len(pIst_from), HANOI_OP_FILE, "a");

  9. base_log_intarr(pIst_to->stname, pIst_to->pArr, pIst_to->len(pIst_to), HANOI_OP_FILE, "a");

  10. return TRUE;

  11. }

  12. }

  13.  
  14. return FALSE;

  15. }




见到, 如果移动成功, 会把移动盘子的信息(从哪里移动到哪, 移动哪个元素) 记录在日志文件, 而且记录每1个移动步骤后, 两个塔里面的元素状态.

其中hanoi_move_str 是外部定义公共变量

 

5.6  输出单个塔里面的元素函数 hanoi_print

实际上就是输出栈里面的所有元素啦, 用于验证嘛..

..

 
  1. void hanoi_print(HANOITOWER * pIst){

  2. pIst->print(pIst);

  3. }



 

 

 

5.7  解题递归函数 hanoi_m

原理和伪算法上面都讲过了啦, 不是吗?  而且有了上面的代码准备, 现在写这个递归函数就十分简单了.

代码如下:

 

 
  1. int hanoi_m(HANOITOWER * pfrom, HANOITOWER * pmid, HANOITOWER *pto, int count){

  2. if (count == 1){

  3. hanoi_move(pfrom, pto);

  4. return 0;

  5. }

  6.  
  7. hanoi_m(pfrom,pto,pmid,count-1);

  8. hanoi_move(pfrom, pto);

  9. hanoi_m(pmid,pfrom,pto,count-1);

  10.  
  11. return 0;

  12. }


 

 

6. 测试这个汉诺塔代码

好了, 所有函数都写好了, 就写1个测试程序验证啊,  n先设为4嘛, 不让日志太长了..

代码如下:

 

 
  1. int hanoi1(){

  2. HANOITOWER * pTa = hanoi_new();

  3. pTa->stname = "TowerA";

  4. HANOITOWER * pTb = hanoi_new();

  5. pTb->stname = "TowerB";

  6. HANOITOWER * pTc = hanoi_new();

  7. pTc->stname = "TowerC";

  8.  
  9. hanoi_move_str = (char *)malloc(sizeof(char) * 50);

  10. int i;

  11.  
  12. for (i=4; i >= 1; i--){

  13. hanoi_push(pTa, i);

  14. }

  15.  
  16. printf("before move\n");

  17. printf("tower A is below\n");

  18. hanoi_print(pTa);

  19. printf("tower B is below\n");

  20. hanoi_print(pTb);

  21. printf("\ntower C is below\n");

  22. hanoi_print(pTc);

  23.  
  24. base_log("start to move\n", HANOI_OP_FILE, "w");

  25.  
  26. hanoi_m(pTa, pTb, pTc, pTa->len(pTa));

  27.  
  28. printf("\nafter move\n");

  29. printf("tower A is below\n");

  30. hanoi_print(pTa);

  31. printf("\ntower B is below\n");

  32. hanoi_print(pTb);

  33. printf("\ntower C is below\n");

  34. hanoi_print(pTc);

  35.  
  36. ast_free(pTa);

  37. ast_free(pTb);

  38. ast_free(pTc);

  39.  
  40. free(hanoi_move_str);

  41. printf("hanoi_new done\n");

  42. return 0;

  43. }


 

 

注意我先移动前先输出3个塔的元素, 移动后再输出1次, 就可以验证了嘛..

输出:  注意看栈的输出元素.

 

 

我上面是不是说了每1次移动我都会记录在日志文件中:

打开来看看就可以知道每一次移动的作用和意义了, 能加深理解哦:

 

 
  1. gateman@TFPC c_start $ cat ~/tmp/HANIO_OP_FILE.log

  2. start to move

  3.  
  4. move 1 from TowerA to TowerB

  5. TowerA: 4, 3, 2

  6. TowerB: 1

  7.  
  8. move 2 from TowerA to TowerC

  9. TowerA: 4, 3

  10. TowerC: 2

  11.  
  12. move 1 from TowerB to TowerC

  13. TowerB: blank array!

  14. TowerC: 2, 1

  15.  
  16. move 3 from TowerA to TowerB

  17. TowerA: 4

  18. TowerB: 3

  19.  
  20. move 1 from TowerC to TowerA

  21. TowerC: 2

  22. TowerA: 4, 1

  23.  
  24. move 2 from TowerC to TowerB

  25. TowerC: blank array!

  26. TowerB: 3, 2

  27.  
  28. move 1 from TowerA to TowerB

  29. TowerA: 4

  30. TowerB: 3, 2, 1

  31.  
  32. move 4 from TowerA to TowerC

  33. TowerA: blank array!

  34. TowerC: 4

  35.  
  36. move 1 from TowerB to TowerC

  37. TowerB: 3, 2

  38. TowerC: 4, 1

  39.  
  40. move 2 from TowerB to TowerA

  41. TowerB: 3

  42. TowerA: 2

  43.  
  44. move 1 from TowerC to TowerA

  45. TowerC: 4

  46. TowerA: 2, 1

  47.  
  48. move 3 from TowerB to TowerC

  49. TowerB: blank array!

  50. TowerC: 4, 3

  51.  
  52. move 1 from TowerA to TowerB

  53. TowerA: 2

  54. TowerB: 1

  55.  
  56. move 2 from TowerA to TowerC

  57. TowerA: blank array!

  58. TowerC: 4, 3, 2

  59.  
  60. move 1 from TowerB to TowerC

  61. TowerB: blank array!

  62. TowerC: 4, 3, 2, 1

 

 

看到n=4 的话 执行了 15次move动作

注意n不要设成太大啊,   不然这个日志会有成千上万行的啊!

分析一下, 从n =1 到n =5 的5个样本

move分别执行了

1 3 7 15 31 ....  (2-1,4-1,8-1,16-1

也就是随着n增长,  move执行次数= 2^n-1

可以看出, 随着n的增长, move的执行次数增长是几何级数的节奏啊!! 所以从时间复杂度O(2^n)来看, 这个递归函数是非常糟糕的. 但是毕竟容易理解和易于实现啊.

 

到底有多糟糕,  我将n设为24, 执行了8分钟才出结果,

move执行了, 1677多万次

日志文件6700多万行,  大小高达1.6 GB,  真是瞎了我的狗眼.

 

最后附上这个汉诺塔程序的代码:

和上面的静态栈文件1齐编译就能执行了

hanoi1.c

C语言递归解决汉诺塔问题(代码含详细注解) C语言递归思想解决汉诺塔问题 阅读详情

相关推荐

汉诺塔问题:C语言实现(递归)和伪代码

C语言实现汉诺塔问题,递归算法代码和伪代码 #include <stdio.h> void hanoi(int,char,char,char); void move(char,char); int main(){ int n; printf("输入汉诺塔的层数:"); scanf("%d",&n); hanoi(n,'A','B','C'); return 0; } void hanoi(int n,char x,char y,char z){ if(n==1){

weixin_44016361的博客 8091

求解汉诺塔问题(提示, 使用递归)

package com.test; import java.util.Scanner; public class Test { //主方法 public static void main(String[] args){ Scanner in = new Scanner(System.in); System.out.println("请输入汉诺塔的层数:"...

helloword233的博客 6778

汉诺塔递归-C语言实现

汉诺塔的游戏网址:http://www.hannuota.cn Hanoi的游戏目的:打印塔A上所有的盘子移动到塔C的所有路径 规则:1.每次仅能移动一次;    2.小的金盘必须在大的金盘上面 思考任何问题我们思维上都应该先从数学的角度去分析,而不是一上来就思考编程如何实现。 假令塔1有1个盘子,直接把其从塔1 -> 塔3 假令塔1有2个盘子,仅需要塔1 -> 塔2,塔1 -> 塔3,塔2 -> 塔3 假令塔1有3个盘子,需要塔1 -> 塔3,塔1 ->

余性笃厚的博客 649

汉诺塔——递归算法(c语言实现)

真的很难,自己总结一下,方便自己看也分享给各位。

m0_74389379的博客 1万+

【C语言】递归详解汉诺塔问题

递归 + 图解详细讲解汉诺塔移动次数和打印的过程

StackFrame 2万+

汉诺塔递归解决方案详解与C语言实现

递归是计算机科学中的一个重要概念,它是一种解决问题的方法,通过函数自我调用来简化问题的求解过程。一个递归函数可以调用自身以解决问题的子集,直到达到基本情况(base case),此时不再调用自身而直接返回结果。递归的基本思想是将一个复杂的问题分解成两个或多个相似的小问题,直到每个小问题简单到可以用一个基本解法直接解决。递归的工作原理依赖于两个重要概念:边界条件(base case)和递归体(recursive case)。边界条件定义了递归结束的条件,防止无限递归的发生。

weixin_31419153的博客 1053

汉诺塔递归的c语言递归实现

#include <iostream> #include <cstdio> using namespace std; void move(int n,char from,char rely,char to) { if(n==1) { printf("%c -> %c\n",from,to); } else { move(n-1,from,to,rely); printf("%c -> %c\n",from,to); move(n-1,rely,

weixin_43774168的博客 184

1173:阶乘和

1173:阶乘和 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 6010 通过数: 3049 【题目描述】 用高精度计算出S=1!+2!+3!+…+n!(n≤50),其中“!”表示阶乘,例如:5!=5×4×3×2×1。 输入正整数n,输出计算结果S。 【输入】 一个正整数n。 【输出】 计算结果S。 【输入样例】 5 【输出样例】 153 思路: ...

zqhf123的博客 1260

递归的实际问题处理——汉诺塔游戏(c语言实现)

汉诺塔问题(c语言)

m0_74996548的博客 191

Kali Linux下Havoc框架编译避坑指南:从环境配置到成功运行的全流程

本文提供了在Kali Linux系统上成功编译和运行Havoc开源框架的详细指南。文章重点解析了从Go语言环境配置、系统依赖库安装到交叉编译环境搭建的全流程,并针对编译过程中常见的Qt、Boost及mingw-w64等依赖问题给出了具体的解决方案,帮助安全研究人员绕过常见陷阱,顺利完成环境部署。

weixin_29230865的博客 94

雷电模拟器+Google Play服务配置全指南:从安装到定位问题解决

本文详细介绍了雷电模拟器配置Google Play服务的全流程,包括版本选择、组件安装、定位服务调试及网络问题排查。针对安卓开发者的常见挑战,提供从基础到高级的解决方案,帮助优化测试环境稳定性与定位精度。

weixin_30399821的博客 1222

用函数递归的方法解决汉诺塔问题

函数递归算法的运用有一个经典例题,那就是汉诺塔问题,接下来就让我们一起来看看如何用函数递归来解决汉诺塔问题叭! 汉诺塔问题的起源: 汉诺塔(又称河内塔)问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次只能搬一个,而且大的不能放在小的上面。面对庞大的数字(移动圆片的次数)18446744073709551615,

2021dragon的博客 8955

DSP28377内存不够用?手把手教你合并RAM/FLASH块,解决CCS20链接器报错

本文详细介绍了在CCS20开发环境中解决DSP28377内存不足问题的方法,通过合并RAM/FLASH块优化CMD文件配置,有效解决链接器报错。文章包含内存布局对比、改写步骤、FreeRTOS集成注意事项及调试技巧,帮助开发者提升内存利用率与项目性能。

weixin_42524762的博客 143

C语言递归思想实现汉诺塔

目录 1.递归思想简介 2.汉诺塔问题 3.汉诺塔递归的c语言实现 1.递归思想简介 在c语言中,程序调用自身的编程技巧称为递归( recursion)。 递归的定义看上去似乎很抽象,使用代码描述能够让人容易理解,下面是一个函数递归的例子。 /* 递归求n的阶乘 */ int factorial(int n) //定义一个求阶乘的函数叫做factorial(),需要一个整形参

weixin_58165485的博客 871

软件自动化测试脚本如何编写,编写自动化测试脚本的几点注意事项

我们需要自动化测试脚本的原因:1、验收测试是一项非常复杂和费力的被用来确保软件质量的环节。它的目的就是使软件能得到充分运行并且能使其符合原始需求。2、测试的目的无非就是满足了两个结果:测试通过或测试不通过。为了能实现每个测试结果,必须要明确每个测试用例。并且对于整个系统而言在合同中必须定义测试用例的失败标准,而且这个失败标准数必须是可接受的。3、测试用例的通过条件必须有一个清晰的标准,标准可以被定...

weixin_39575775的博客 2251

告别安装报错!保姆级教程:用阿狸狗破戒大师V3.2.6搞定Cadence 17.4完整安装与补丁

本文提供Cadence 17.4的完整安装与破解教程,特别针对国内用户常见问题优化。从前期准备、镜像处理到阿狸狗破戒大师V3.2.6的智能破解,再到补丁管理与性能调优,详细指导每一步操作,确保一次性安装成功并提升设计效率。

weixin_30632089的博客 832

C语言:函数递归详解(建议收藏)

程序调用自身的编程技巧称为递归。递归做为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。

心仔的博客 5万+

【AI智能体】Claude Code +Superpowers 项目实战操作详解

Claude Code +Superpowers 项目实战操作详解

congge 4044

【C】青蛙跳台阶和汉诺塔问题(递归)

这篇博客总结递归当中俩个经典的问题,青蛙跳台阶和汉诺塔,用C语言实现!

trong_ 的烂笔头 1617

芒果YOLO11改进137:卷积AKConv篇,即插即用,具有任意采样形状和任意数量的参数的卷积内核

卷积AKConv篇,即插即用,具有任意采样形状和任意数量的参数的卷积内核

包括YOLOv5、YOLOv7、YOLOv8等模型改进 295

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C语言递归实现汉诺塔问题

在使用递归前我们首先要知道什么是递归: 程序调用自身的编程技巧称为递归( recursion)。 递归的作用: 递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。这里是引用 ...

qq_43422165的博客 1693

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

《递归:C语言中的强大工具》

递归:C语言中的强大工具

一名普通高校生 1847

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C语言----汉诺塔问题----小白的试探与复盘

C语言—汉诺塔----小白的试探与复盘 问题: 汉诺塔问题是一个著名的问题,初始模型如图所示。其来源据说是在约19世纪末欧洲的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆自上而下、由小到大顺序串着64个圆盘构成的塔,游戏的目的是将最左边A杆上的圆盘,借助最右边的C杆,全部移动到中间的B杆上,条件是一次仅能移动一个盘,且不允许大盘放在小盘的上面。 第一步: 把n-1个木块,从A移动到B; 把第N个木块,从A移动到C; 第二部: 把n-1个木块,从B移动到C(与从A移动到B其实是一样的,只不过是换

mstcoder的博客 4862

c语言 汉诺塔游戏下载,使用C语言解决益智游戏——“汉诺塔”

说明:文章所有内容截选自实验楼教程【3个C语言实例带你掌握递归方法论】,教程里还有两个实例,感兴趣的可以点击查看;文章主要是带你通过解决这个游戏来利用递归解决实际问题并掌握其核心思想,懂得如何使用递归解决实际问题;“汉诺塔”游戏规则首先,我们来看一下“汉诺塔”游戏规则:有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:每次只能移...

weixin_39605004的博客 202

c语言递归汇编层原理,C语言-数据结构-递归

一.简介在哔哩哔哩看视频学的,赫斌老师数据结构入门的内容-b站搜索:av6159200(P50-P58),因为我在早期学c语言的时候就学过的递归,那时一直理解不了汉诺塔,最后花了很长时间才彻底搞懂,在看到学到这个数据结构有递归的时候,自己就重新写了一下汉诺塔递归的实现,不过通过了视频了解了大致递归的一下原理把.二.什么是递归递归其实说得简单点,大概就是自己调用自己,或者调用别的函数,并且递归要有结...

weixin_39641334的博客 275
上一篇: 如何利用循环代替递归以防止栈溢出(译)
下一篇: 栈溢出示例
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值