快速解析 递归与分治思想

分治思想:    
 斐波那契数列的迭代实现:(兔子繁殖问题)

 

  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int i;
  5.     int a[40];
  6.     a[0] = 0;
  7.     a[1] = 1;
  8.     for(i = 2; i < 40; i++)
  9.     {
  10.         a[i] = a[i - 1] + a[i - 2];
  11.         printf("%d", a[i]);
  12.     }
  13.     return 0;
  14. }

    
斐波那契数列的递归实现:(兔子繁殖问题)  

  1. int Fib(int i)
  2. {
  3.     if(i < 2)
  4.         return i == 0 ? 0 : 1;
  5.     return Fib(i - 1) + Fib(i - 2);
  6. }

    
对比以上两个代码发现

  1. 迭代和递归的区别是:迭代使用的是循环结构,递归使用的是选择结构
  2. 使用递归使程序的结构更清晰,更简洁,更容易让人理解,从而减少读懂代码的时间
  3. 大量的递归调用会减少函数的副本,会消耗大量的时间和内存,而迭代则不需要此种付出
  4. 递归函数分为调用和回退阶段,递归的回退顺序是它调用顺序的逆序

      
折半查找算法的递归实现:

    
    折半查找法是一种常用的查找方法,该方法通过不断缩小一半查找的范围,知道达到目的。

    
汉诺塔问题实现:

 

  1. //将 n 个盘子从 x 借助 y 移动到 z
  2. void move(int n, char x, char y, char z)
  3. {
  4.     if(1 == n)
  5.     {
  6.         printf("%c --> %c\n", x, z);
  7.     }
  8.     else
  9.     {
  10.         move(n - 1, x, z, y); //将 n - 1 个盘子从 x 借助 z 移动到 y 上
  11.         printf("%c --> %c\n", x, z); //将第 n 个盘子从 x 移动到 z 上
  12.         move(n - 1, y, x, z); //将 n - 1 个盘子从 y 借助 x 移动到 z 上
  13.     }
  14. }
  15. int main()
  16. {
  17.     int n;
  18.     printf("请输入层数: ");
  19.     scanf("%d", &n);
  20.     move(n, 'X','Y', 'Z');
  21.     return 0;
  22. }

 
    八皇后问题:     
    在 8 X 8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行,同一列或同一斜线上,共用多少种摆法?  

  1. #include <stdio.h>
  2. int count = 0;
  3. int notdanger(int row, int j, int (*chess)[8])
  4. {
  5.     int i, flag1, flag2, flag3, flag4, flag5;
  6.     //判断列方向
  7.     for(i = 0; i < 8; i++)
  8.     {
  9.         if(*(*(chess + i) + j) != 0)
  10.         {
  11.         flag1 = 1;
  12.          break;
  13.         }
  14.     }
  15.     //判断左上方
  16.     for(i = row, k = j; i < 8 && k < 8; i++, k++)
  17.     {
  18.         if(*(*(chess + i) + k) != 0)
  19.         {
  20.             flag2 = 1;
  21.             break;
  22.         }
  23.     }
  24.     //判断右下方
  25.     for( i = row, k = j; i < 8 && k < 8; i ++, k ++)
  26.     {
  27.         if(*(*(chess + i) + k ) != 0)
  28.         {
  29.             flag3 = 1;
  30.             break;
  31.         }
  32.     }
  33.     //判断右上方
  34.     for( i = row, k = j; i >= 0 && k < 8; i--, k++)
  35.     {
  36.         if(*(*(chess + i) + k) != 0)
  37.         {
  38.             flag4 = 1;
  39.             break;
  40.         }
  41.     }
  42.     //判断左下方
  43.     for( i = row, k = j; i < 8 && k >= 0; i++, k--)
  44.     {
  45.         if(*(*(chess + i) + k) != 0)
  46.         {
  47.             flag5 = 1;
  48.             break;
  49.         }
  50.     }
  51.     if( flag1 || flag2 || flag3 || flag4 || flag5)
  52.     {
  53.         return 0;
  54.     }
  55.     else
  56.     {
  57.         return 1;
  58.     }
  59. }
  60. //参数row :表示起始行
  61. //参数n :表示列数
  62. //参数(*chess)[8] : 表示指向棋盘每一行的指针
  63. void EightQueen(int row, int n, int (*chess)[8])
  64. {
  65.     int chess2[8][8], i, j;
  66.     for(i = 0; i < 8; i++)
  67.     {
  68.         for(j = 0; j < 8; j++)
  69.         {
  70.         chess2[i][j] = chess[i][j];
  71.         }
  72.     }
  73.     if(8 == row)
  74.     {
  75.         printf("第 %d 种" count + 1);
  76.         for(i = 0; i < 8; i++)
  77.         {
  78.             for(j = 0; j < 8; j++)
  79.             {
  80.                 printf("%d", *(*(chess2 + i) +j));
  81.             }
  82.             printf("\n");
  83.         }
  84.         printf("\n");
  85.         count++;
  86.     }
  87.     else
  88.     {
  89.         for(j = 0; j < n; j++)
  90.         {
  91.          if( notdanger(row, j, chess) ) //判断是否危险
  92.          {
  93.                 for( i = 0; i < 8; i++)
  94.                 {
  95.                     *(*(chess2 + row) + i) = 0;
  96.                 }
  97.                 *(*(chess2 + row) + i) = 1;
  98.                 EightQueen(row + 1, n, chess2);
  99.          }
  100.         }
  101.     }
  102. }
  103. int main()
  104. {
  105.     int chess[8][8], i, j;
  106.     for(i = 0; i < 8; i++)
  107.     {
  108.         for(j = 0; j < 8 ; j++)
  109.         {
  110.         chess[i][j] = 0;
  111.         }    
  112.     }
  113.     EightQueen(0, 8, chess);
  114.     printf(“总共有 %d 种解决方法!\n”, count);
  115.     return 0;
  116. }
    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/qq_26626709/article/details/52203949
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞