递归算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归算法相关的知识,希望对你有一定的参考价值。

1.递归算法的理解

   递归算法是一种直接或间接调用自身方法的算法,递归往往可以使我们的代码大大简化,而递归的思维却跟我们正常思维相逆,通常都是自上而下的思考问题,而递归是自下而上。

2.写递归时的注意点

  1.在使用递归时,必须有一个明确的递归结束条件,称为递归出口。

  2.递归方法即可有返回值也可没有。

  3.递归过程中每个方法都会产生一个栈帧存放到方法栈中,因此,如果递归出口没把握好,就会造成内存溢出。

  4.在进入第二次递归之前不会执行下面的逻辑。

3.递归应用

  1.Fibonacci数列

 1 package recursion;
 2 
 3 import org.junit.Test;
 4 
 5 /**
 6  * Created by 14611 on 2017/7/30.
 7  */
 8 public class RecursionTest {
 9     /**
10      * 测试在进入第二次递归之前是否执行下面的逻辑
11      * 结论:不会。
12      */
13     @Test
14     public void testFibonaci() {
15         System.out.println("result= "+fibonaci(5));
16     }
17 
18     /**
19      * 1,1,2,3,5,8...Fibonaci数列
20      *
21      * @param n
22      * @return
23      */
24     public int fibonaci(int n) {
25         if (n <= 2) {
26             return 1;
27         } else {
28             int value = fibonaci(n - 1) + fibonaci(n - 2);
29             System.out.println("Hello!" + n);
30             return value;
31         }
32     }
33 }

 

  2.构造树(递归报文或JSONObject)

  

package tree;

import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 14611 on 2017/7/30.
 * 树节点
 */
public class TreeNode {
    //节点id
    int nodeId;
    //父节点id
    Integer parentId;
    //节点信息
    JSONObject nodeJson;
    //所有子节点
    List<TreeNode> subTreeNodes = new ArrayList<TreeNode>();

    public void setNodeId(int nodeId) {
        this.nodeId = nodeId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public void setNodeJson(JSONObject nodeJson) {
        this.nodeJson = nodeJson;
    }

    public int getNodeId() {
        return nodeId;
    }

    public Integer getParentId() {
        return parentId;
    }

    public JSONObject getNodeJson() {
        return nodeJson;
    }

    public List<TreeNode> getSubTreeNodes() {
        return subTreeNodes;
    }

    /**
     * 添加子节点
     *
     * @param treeNode
     */
    public void addSubNode(TreeNode treeNode) {
        this.subTreeNodes.add(treeNode);
    }
}

  

 

package tree;

import java.util.List;
import java.util.Map;

/**
 * Created by 14611 on 2017/7/30.
 * 树
 */
public class Tree {
    //所有树节点
    Map<Integer, TreeNode> allTreeNodeMap;

    /**
     * 根据树的根节点构造树
     *
     * @param rootNode
     */
    public Tree(TreeNode rootNode) {
        initTree(rootNode);
    }

    /**
     * 根据树节点递归初始化tree
     *
     * @param rootNode
     */
    private void initTree(TreeNode rootNode) {
        allTreeNodeMap.put(rootNode.getNodeId(), rootNode);
        List<TreeNode> subTreeNodes = rootNode.getSubTreeNodes();
        if (!subTreeNodes.isEmpty()) {
            for (TreeNode subTreeNode : subTreeNodes) {
                initTree(subTreeNode);
            }
        }
    }
}

  

package tree;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * Created by 14611 on 2017/7/30.
 * 用于管理树和树节点
 */
public class TreeManager {
    Tree tree;
    //指明JSON中按那个节点递归
    String rootName;
    String subName;

    public TreeManager(JSONObject recursJson, String rootName, String subName) {
        this.rootName = rootName;
        this.subName = subName;
        //根节点
        TreeNode rootNode = getNode(recursJson);
        rootNode.setParentId(null);
        JSONArray subArray = recursJson.getJSONArray(subName);
        //构造树
        conTree(rootNode, subArray);
        this.tree = new Tree(rootNode);
    }

    /**
     * 实际上是构造根节点
     * @param rootNode
     * @param subArray
     */
    private void conTree(TreeNode rootNode, JSONArray subArray) {
        if (subArray == null) {
            return;
        }
        for (int i = 0; i < subArray.size(); i++) {
            JSONObject jsonObject = subArray.getJSONObject(i);
            TreeNode node = getNode(jsonObject);
            node.setParentId(rootNode.getNodeId());
            rootNode.addSubNode(node);
            JSONArray sub = jsonObject.getJSONArray(subName);
            conTree(node, sub);
        }
    }

    /**
     * 根据递归的json得到当前树节点
     *
     * @param recursJson
     * @return
     */
    private TreeNode getNode(JSONObject recursJson) {
        String root = recursJson.getString(rootName);
        int id = root.hashCode();
        TreeNode treeNode = new TreeNode();
        treeNode.setNodeId(id);
        treeNode.setNodeJson(recursJson);
        return treeNode;
    }
}

  

以上是关于递归算法的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript - 代码片段,Snippets,Gist

以下代码片段的算法复杂度

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]

片段(Java) | 机试题+算法思路+考点+代码解析 2023

CSP核心代码片段记录

算法漫游指北(第十篇):泛型递归递归代码模板递归思维要点分治算法回溯算法