问题原因
实践二叉树层次遍历时,出现这个报错,开始以为是循环引用导致栈溢出。
后来发现问题原因如下:
因为属性引用子属性,导致toString方法会不断调用子节点的属性。最终栈溢出。
解决方案
重写toString方法,注意不要打印调用子节点的属性!!
最后贴一段树的层次遍历实现代码。
package com.zouch.onetoten;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import java.util.*;
/**
* @author Zouch
* @date 2021/8/25 下午1:13
* 树的层次遍历(没有限制必须是二叉树)
* 思想:
* 使用队列,出循环的条件是队列元素为空。
* 每次出队一个节点都判断,当队列中有节点时,将其孩子都加入队列
* 然后把节点加入list中
*/
@Getter
@Setter
public class TreeOfBfs {
private TreeNode rootNode;
@Override
public String toString() {
return "TreeOfBfs{" +
"rootNode=" + rootNode +
'}';
}
@Data
public static class TreeNode {
private Object key;
private TreeNode parent;
private List<TreeNode> treeNodes;
@Override
public String toString() {
return "TreeNode{" +
"key=" + key +
", parent=" + parent;
}
}
public static List<TreeNode> levelTraverse(TreeNode rootNode) {
if (Objects.isNull(rootNode)) {
return null;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.add(rootNode);
List<TreeNode> list = new LinkedList<>();
while (queue.size() > 0) {
TreeNode poll = queue.poll();
list.add(poll);
List<TreeNode> treeNodes = poll.getTreeNodes();
if (CollectionUtils.isEmpty(treeNodes)){
continue;
}
queue.addAll(treeNodes);
}
return list;
}
public static void main(String[] args) {
TreeOfBfs treeOfBfs = new TreeOfBfs();
TreeNode rootNode = new TreeNode();
treeOfBfs.setRootNode(rootNode);
TreeNode node1 = new TreeNode();
node1.setParent(rootNode);
node1.setKey("左孩子1");
TreeNode node2 = new TreeNode();
node2.setParent(rootNode);
node2.setKey("右孩子2");
TreeNode node3 = new TreeNode();
node3.setParent(node2);
node3.setKey("左孩子3");
TreeNode node4 = new TreeNode();
node4.setParent(node2);
node4.setKey("右孩子4");
List<TreeNode> treeNodes = new ArrayList<>();
treeNodes.add(node1);
treeNodes.add(node2);
rootNode.setTreeNodes(treeNodes);
List<TreeNode> treeNodes2 = new ArrayList<>();
treeNodes2.add(node3);
treeNodes2.add(node4);
node2.setTreeNodes(treeNodes2);
List<TreeNode> result = levelTraverse(rootNode);
System.out.println(result.toString());
}
}