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