java 树节点递归

类似的博文其实数量并不少,但觉得不少博文还是比较乱而且有点复杂化了,所以决定尝试写一篇简单易懂的博文...

 由于树节点一般无法确定它的级层数,所以遍历树的节点传统方法一般可使用递归函数。

递归函数的好处是代码更简单易读,但是缺点就是树的层级太深可能会导致内存溢出,下面顺便写出递归遍历树的简略代码:

假设有个需求,需要遍历查找到code相等的树节点,然后返回这些节点。

 

递归方法的实现:

//递归遍历树,主函数入口
public List<Node> findCodeListByTree(List<String> codeList) {
    List<Node> nodeList = new ArrayList<Node>();  //储存节点
    Node rootNode = tree.getRootNode();   //获取根节点
    for(String code : codeList) {
        nodeList.addAll(findNodeByChildren(rootNode,code));  
    } 
    return nodeList;
}

//递归方法
public List<Node> findNodeByChildren(Node node,String code) {
    List<Node> nodeList = new ArrayList<Node>();
    if(code.equals(node.getCode())) {
         nodeList.add(node);
    }
    Node childNode = node.getChildren();
    if(childNode != null) {
        nodeList.addAll(findNodeByChildren(childNode,code));
    }
    return nodeList;
}

 

其中也可以使用非递归函数实现,个人更倾向于这种实现方式。

非递归,深度优先遍历树,说白了就是使用Stack先进后出的特性

//递归遍历树,主函数入口
public List<Node> findCodeListByTree(List<String> codeList) {
    List<Node> nodeList = new ArrayList<Node>();  //储存节点
    Stack<Node> nodeStack = new Stack<Node>();    //节点栈
    Node rootNode = tree.getRootNode();   //获取根节点
    nodeStack.add(rootNode);
    for(String code : codeList) {
        while(!nodeStack.isEmpty()) {
            Node node = nodeStack.pop();
            if(node.getCode().equals(code)) {
                nodeList.add(node);
            }
            List<Node> childrenNode = node.getChildren();
            nodeStack.addAll(childrenNode);
        } 
    } 
    return nodeList;
}

非递归,广度优先遍历树,可利用Queue先进先出的特性

//递归遍历树,主函数入口
public List<Node> findCodeListByTree(List<String> codeList) {
    List<Node> nodeList = new ArrayList<Node>();  //储存节点
    Queue<Node> nodeQueue = new LinkedList<Node>();    //节点栈
    Node rootNode = tree.getRootNode();   //获取根节点
    nodeQueue.offer(rootNode);
    for(String code : codeList) {
        while(!nodeQueue.isEmpty()) {
            Node node = nodeQueue.poll();
            if(node.getCode().equals(code)) {
                nodeList.add(node);
            }
            List<Node> childrenNode = node.getChildren();
            nodeQueue.addAll(childrenNode);
        } 
    } 
    return nodeList;
}

 

由于实际树的数据很多场景都并非是二叉树,这里只给出比较简单的遍历树方法,前中后序的遍历以后有时间可以补充,如果有不对的地方欢迎指出!