[关闭]
@yanglt7 2018-10-21T15:50:32.000000Z 字数 4271 阅读 589

06_递归

数据结构和算法


6.1 斐波那契数列的迭代实现

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

6.2 斐波那契数列的递归实现

  1. #include <stdio.h>
  2. int Fib(int i)
  3. {
  4. if( i < 2 )
  5. return i == 0 ? 0 : 1;
  6. return Fib(i-1) + Fib(i-2);
  7. }
  8. int main()
  9. {
  10. int i = 0;
  11. printf("请输入需要打印的斐波那契列数: ");
  12. scanf("%d", &i);
  13. printf("%d ", Fib(i));
  14. return 0
  15. }

6.3 递归定义

计算 n 的阶乘 n!

  1. #include <stdio.h>
  2. int factorial(n)
  3. {
  4. if( 0 == n )
  5. return 1;
  6. else
  7. return n*factorial(n-1);
  8. }
  9. int main()
  10. {
  11. int n = 0;
  12. printf("请输入需要计算阶乘的数字 n : ");
  13. scanf("%d", &n);
  14. printf("%d\n", factorial(n));
  15. return 0;
  16. }

6.4 实例分析

编写一个递归函数,实现将输入的任意长度的字符串反向输出的功能。

  1. #include <stdio.h>
  2. void print()
  3. {
  4. char a;
  5. scanf("%c", &a);
  6. if( a != '#' )
  7. print();
  8. if( a != '#' )
  9. printf("%c", a);
  10. }
  11. int main()
  12. {
  13. printf("请输入字符串,并以 # 作为结束标志!\n");
  14. print();
  15. return 0;
  16. }

6.5 分治思想

折半查找法的迭代实现

  1. //折半查找法的迭代实现 1
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int bin_serach(int str[], int n, int key)
  5. {
  6. int low, mid, high;
  7. low = 0;
  8. high = n - 1;
  9. while(low <= high)
  10. {
  11. mid = (low + high)/2;
  12. if (str[mid] == key)
  13. {
  14. return mid;
  15. }
  16. else if (str[mid] < key)
  17. {
  18. low = mid + 1;
  19. }
  20. else {
  21. high = mid - 1;
  22. }
  23. }
  24. return 0;
  25. }
  26. int main()
  27. {
  28. const int SIZE = 10;
  29. int c;
  30. int i = 0;
  31. int str[SIZE];
  32. printf("请输入 %d 个数字作为初始数组:\n", SIZE);
  33. while( i < SIZE )
  34. {
  35. scanf("%d", &c);
  36. str[i] = c;
  37. i++;
  38. }
  39. int n, addr;
  40. printf("\n请输入要查询的数字:");
  41. scanf("%d", &n);
  42. addr = bin_serach(str, SIZE, n);
  43. if (-1 != addr)
  44. {
  45. printf("查找成功,查询数字 %d 所在的位置是: %d\n", n, addr+1);
  46. }
  47. else
  48. {
  49. printf("查找失败!");
  50. }
  51. return 0;
  52. }
  1. //折半查找法的迭代实现 2
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int getAddr(int str[], int key, int low, int high)
  5. {
  6. if (low > high)
  7. return -1;
  8. int mid = (low + high) / 2;
  9. if (key == str[mid])
  10. return mid;
  11. if (str[mid] < key)
  12. {
  13. low = mid + 1;
  14. }
  15. else if (str[mid] > key)
  16. {
  17. high = mid - 1;
  18. }
  19. return getAddr(str, key, low, high);
  20. }
  21. int main()
  22. {
  23. const int SIZE = 10;
  24. int c;
  25. int i = 0;
  26. int str[SIZE];
  27. printf("请输入 %d 个数字作为初始数组:\n", SIZE);
  28. while( i < SIZE )
  29. {
  30. scanf("%d", &c);
  31. str[i] = c;
  32. i++;
  33. }
  34. int n, addr;
  35. printf("\n请输入要查询的数字:");
  36. scanf("%d", &n);
  37. addr = getAddr(str, n, 0, SIZE);
  38. if (-1 != addr)
  39. {
  40. printf("查找成功,查询数字 %d 所在的位置是: %d\n", n, addr+1);
  41. }
  42. else
  43. {
  44. printf("查找失败!");
  45. }
  46. return 0;
  47. }

折半查找法的递归实现

  1. //折半查找法的递归实现
  2. #include <stdio.h>
  3. typedef int ElemType;
  4. int half_search(ElemType *str, int low, int high, ElemType n)
  5. {
  6. int mid = (low + high)/2;
  7. if(low > high)
  8. return -1;
  9. if( str[mid] == n )
  10. {
  11. return mid;
  12. }
  13. else if( str[mid] < n )
  14. {
  15. return half_search(str, mid+1, high, n);
  16. }
  17. else
  18. {
  19. return half_search(str, low, mid-1, n);
  20. }
  21. }
  22. int main()
  23. {
  24. const int SIZE = 10;
  25. ElemType str[SIZE];
  26. int c;
  27. int i = 0;
  28. printf("请输入 %d 个数字作为初始数组:\n", SIZE);
  29. while( i < SIZE )
  30. {
  31. scanf("%d", &c);
  32. str[i] = c;
  33. i++;
  34. }
  35. printf("\n");
  36. for( i=0; i<SIZE; i++ )
  37. {
  38. printf("%d ", str[i]);
  39. }
  40. int n;
  41. printf("\n请输入要查询的数字:");
  42. scanf("%d", &n);
  43. int addr = half_search(str, 0, SIZE, n);
  44. if (-1 != addr)
  45. {
  46. printf("查找成功,查询数字 %d 所在的位置是: %d\n", n, addr+1);
  47. }
  48. else
  49. {
  50. printf("查找失败!");
  51. }
  52. return 0;
  53. }

6.6 汉诺塔

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

6.7 八皇后问题

  1. #include <stdio.h>
  2. int count = 0;
  3. int notDanger( int row, int j, int (*chess)[8] )
  4. {
  5. int i, k, flag1=0, flag2=0, flag3=0, flag4=0, flag5=0;
  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>=0 && k>=0; 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 种\n", 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)+j) = 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. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注