第二篇 递归思想

   今天说说递归思想,在我们编码时,有的时候递归能够让我们的算法更加通俗易懂,并且代码量也是大大的减少。比如我先前的系列中说到了

关于树的“先序,中序和后序”遍历,那么看看用递归来描叙这个问题是多少的简洁,多么的轻松。

复制代码
 1 #region 二叉树的先序遍历
 2          /// <summary>
 3  /// 二叉树的先序遍历
 4  /// </summary>
 5  /// <typeparam name="T"></typeparam>
 6  /// <param name="tree"></param>
 7          public void BinTree_DLR<T>(ChainTree<T> tree)
 8          {
 9              if (tree == null)
10                  return;
11  
12              //先输出根元素
13              Console.Write(tree.data + "	");
14  
15              //然后遍历左子树
16              BinTree_DLR(tree.left);
17  
18              //最后遍历右子树
19              BinTree_DLR(tree.right);
20          }
21          #endregion
22  
23          #region 二叉树的中序遍历
24          /// <summary>
25  /// 二叉树的中序遍历
26  /// </summary>
27  /// <typeparam name="T"></typeparam>
28  /// <param name="tree"></param>
29          public void BinTree_LDR<T>(ChainTree<T> tree)
30          {
31              if (tree == null)
32                  return;
33  
34              //优先遍历左子树
35              BinTree_LDR(tree.left);
36  
37              //然后输出节点
38              Console.Write(tree.data + "	");
39  
40              //最后遍历右子树
41              BinTree_LDR(tree.right);
42          }
43          #endregion
44  
45          #region 二叉树的后序遍历
46          /// <summary>
47  /// 二叉树的后序遍历
48  /// </summary>
49  /// <typeparam name="T"></typeparam>
50  /// <param name="tree"></param>
51          public void BinTree_LRD<T>(ChainTree<T> tree)
52          {
53              if (tree == null)
54                  return;
55  
56              //优先遍历左子树
57              BinTree_LRD(tree.left);
58  
59              //然后遍历右子树
60              BinTree_LRD(tree.right);
61  
62              //最后输出节点元素
63              Console.Write(tree.data + "	");
64          }
65          #endregion
复制代码

看看,多么简洁明了。当然递归都是可以改成非递归的,但是就不见得简洁和通俗易懂了。

一: 概念

       递归,说白了就是直接或者间接的调用自己的一种算法。它是把求解问题转化为规模较小的子问题,然后通过多次递归一直到可以得出结果

的最小解,然后通过最小解逐层向上返回调用,最终得到整个问题的解。总之递归可以概括为一句话就是:“能进则进,不进则退”。

二:三要素

      <1>  递归中每次循环都必须使问题规模有所缩小。

      <2>  递归操作的每两步都是有紧密的联系,如在“递归”的“归操作时”,前一次的输出就是后一次的输入。

      <3>  当子问题的规模足够小时,必须能够直接求出该规模问题的解,其实也就是必须要有结束递归的条件。

三: 注意

       <1>  前面也说了,递归必须要有一个递归出口。

       <2>  深层次的递归会涉及到频繁进栈出栈和分配内存空间,所以运行效率比较低,当问题规模较大时,不推荐使用。

       <3>  在递归过程中,每次调用中的参数,方法返回点,局部变量都是存放在堆栈中的,如果当问题规模非常大时,容易造成堆栈溢出。

原文地址:https://www.cnblogs.com/mmcmmc/p/3946138.html