在Java中实现树形结构的常见方式有以下几种,每种方法适用于不同的场景:
1. 自定义节点类(基础实现)
通过定义节点类,包含子节点的集合(如 List<T>
),适合通用树结构。
class TreeNode<T> {
T data;
List<TreeNode<T>> children;
public TreeNode(T data) {
this.data = data;
this.children = new ArrayList<>();
}
}
// 示例用法
TreeNode<String> root = new TreeNode<>("Root");
root.children.add(new TreeNode<>("Child1"));
适用场景:多叉树、普通树结构。
2. 二叉树节点类
每个节点包含左、右子节点,适用于二叉树。
class BinaryTreeNode<T> {
T data;
BinaryTreeNode<T> left;
BinaryTreeNode<T> right;
public BinaryTreeNode(T data) {
this.data = data;
}
}
// 示例用法
BinaryTreeNode<Integer> root = new BinaryTreeNode<>(1);
root.left = new BinaryTreeNode<>(2);
root.right = new BinaryTreeNode<>(3);
适用场景:二叉树、二叉搜索树、堆结构。
3. 数组表示法
使用数组存储节点,通过索引计算父子关系,适用于完全二叉树。
// 示例:完全二叉树的数组表示
Integer[] treeArray = new Integer[10];
treeArray[0] = 1; // 根节点
treeArray[1] = 2; // 左子节点(索引0的左孩子)
treeArray[2] = 3; // 右子节点(索引0的右孩子)
适用场景:堆、完全二叉树。
4. Map 表示法
使用 Map<T, List<T>>
存储父子关系,适合快速查找子节点。
Map<String, List<String>> treeMap = new HashMap<>();
treeMap.put("Root", Arrays.asList("Child1", "Child2"));
treeMap.put("Child1", Arrays.asList("Grandchild1"));
适用场景:需要快速查找子节点的场景(如某些算法题)。
5. Java集合框架的树结构
使用 TreeSet
或 TreeMap
(基于红黑树实现,自动排序)。
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1); // 内部按升序排列(1, 3)
TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("B", 2);
treeMap.put("A", 1); // 按键排序(A, B)
适用场景:需要有序存储或快速查找/插入/删除。
6. 邻接表表示法
使用列表或数组存储每个节点的邻接节点,适合处理图或树。
List<List<Integer>> adjacencyList = new ArrayList<>();
adjacencyList.add(Arrays.asList(1, 2)); // 根节点0的子节点1和2
adjacencyList.add(new ArrayList<>()); // 节点1无子节点
适用场景:多叉树、图的遍历(如BFS/DFS)。
7. 第三方库
-
Apache Commons Collections: 提供
Tree
接口。 - Google Guava: 使用
TreeTraverser
简化遍历。
// 示例:Guava的树遍历
TreeTraverser<TreeNode<String>> traverser = new TreeTraverser<>() {
@Override
public Iterable<TreeNode<String>> children(TreeNode<String> root) {
return root.children;
}
};
适用场景:需要快速实现复杂操作(如遍历、查找)。
选择建议
-
简单树结构:自定义节点类。
-
完全二叉树:数组表示法(节省空间)。
-
需自动排序:
TreeSet
/TreeMap
。 -
算法题或快速查找:Map或邻接表。