数据结构总结 之 递归

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Albert_Bolt/article/details/82356551

递归

定义
  • 若一个对象部分地包含它自己, 或用它自己给自己定义, 则称这个对象是递归的;若一个过程直接地或间接地调用自己, 则称这个过程是递归的过程。
三种递归情况
  • 定义是递归的
    • 阶乘函数:n=0,n! = 1;n>=1,n! = n*(n-1)!
    • 斐波那契数列:n<=1,fib(n) = n;n>1,fib(n) = fib(n-1) + fib(n-1)
  • 数据结构是递归的
    • 单链表:递归找某一值为x的节点,若节点值为x,则返回节点数值;若节点值不为x,则递归找节点。
  • 问题的解法是递归的
    • 汉诺塔问题:有ABC三根柱子,A上有一些盘子,按从小到大顺序放置,把A上的盘子移到C上,并且要保证盘子也是按照从小到大顺序放置。求这个移动的过程。如果 n = 1,则将这一个盘子直接从 A 柱移到 C 柱上。否则,执行以下三步:
      ① 用 C 柱做过渡,将 A 柱上的 (n-1) 个盘子移到 B 柱上:
      ② 将 A 柱上最后一个盘子直接移到 C 柱上;
      ③ 用 A 柱做过渡,将 B 柱上的 (n-1) 个盘子移到 C 柱上。
递归过程改为非递归过程
  • 递归过程效率低,重复计算多,改为非递归过程的目的是提高效率
  • 单向递归和尾递归可直接用迭代实现其非递归过程
  • 其他情形必须借助栈实现非递归过程
应用1:n皇后问题
  • 在 n 行 n 列的国际象棋棋盘上,若两个皇后位于同一行、同一列、同一对角线上,则称为它们为互相攻击。n皇后问题是指找到这 n 个皇后的互不攻击的布局。
  • 解决:
    • 在第 i 行放皇后时,需要在列的方向从 0 到 n-1 试探 ( j = 0, …, n-1 )
    • 在第 j 列放一个皇后,如果在列、主对角线、次对角线方向有其它皇后,则出现攻击,撤消在第 j 列安放的皇后。如果没有出现攻击,在第 j 列安放的皇后不动,递归安放第 i+1行皇后。
应用2:骑士问题
  • 骑士问题是在一个N*N的棋盘上,给骑士一个起始坐标,骑士必须从起点开始行走,把棋盘上的每一点都走过。骑士的走法就是国际象棋中的骑士走法。
  • 解决:
    • 将八个可能的移动方向使用数组来存放
    • 在移动之前必须另外判断下一步有没有走出了边界
    • 当骑士走到某一位置时,下一个移动的位置是八个位置中的其中一个,从0这个方向开始走,如果新位置未走过的话,就可以移到新位置上,并记录下所走的步数,如果新位置已被走过,则继续找下一个方向。
    • 递归的终止条件为:骑士所走的步数等于N*N
      (由于是N * N的棋盘,所以骑士必须走N2-1步,才能将棋盘上的每一点都走过,即棋盘的大小排除一开始的起始位置那一点。因此若设起点为第一步,则全部走完时最后一步的步数会刚好是棋盘的大小N * N,所以,骑士所走的步数等于N * N,则代表骑士已经全部走完。)
应用3:十进制转换为八进制:
  • 令递归函数为fun,要转换的数为num
  • 如果 num<=8,返回 num
  • 然后递归求 num / 8 的返回值,用这个值 乘以 10 加上 num 模 8 就是最后的结果
 if(num<=8) return num;
 return num % 8 + 10 * func(num/8);

猜你喜欢

转载自blog.csdn.net/Albert_Bolt/article/details/82356551