如何实现树结构非根节点解绑(子节点自动挂载至原父节点)
树结构节点解绑功能实现
核心实现逻辑
严格对齐需求规则,节点解绑需完成三个固定动作:
- 根节点(
parent属性为null)的解绑操作直接终止,不修改任何树结构 - 非根节点解绑时,将自身所有子节点的父引用重定向到当前节点的原父节点,并把这些子节点加入原父节点的子节点集合
- 将当前待解绑节点从原父节点的子节点集合中移除,清空自身关联引用,成为完全独立的孤立节点
代码实现(基于原有Tree类扩展)
直接在原有Tree<T>类中新增解绑方法,无需修改原有类的其他结构:
public class Tree<T> { private T value; private Tree<T> parent; private Set<Tree<T>> children; public Tree(T value) { this.value = value; this.children = new HashSet<>(); } /** * 节点解绑方法 * 规则:根节点不支持解绑,子节点自动迁移到原父节点下 */ public void unbind() { // 根节点无父节点,直接返回无效操作 if (this.parent == null) { return; } Tree<T> originalParent = this.parent; // 逐个将子节点迁移到原父节点下 for (Tree<T> child : this.children) { child.setParent(originalParent); originalParent.getChildren().add(child); } // 从原父节点的子列表中移除当前节点 originalParent.getChildren().remove(this); // 切断当前节点的所有关联 this.parent = null; this.children.clear(); } // 以下为原有类的方法,保持不变 public Tree<T> getParent() { return parent; } public void setParent(Tree<T> parent) { this.parent = parent; } public T getValue() { return value; } public void setValue(T value) { this.value = value; } public Set<Tree<T>> getChildren() { return children; } public Tree<T> addChild(T value) { Tree<T> newChild = new Tree<>(value); newChild.setParent(this); this.children.add(newChild); return newChild; } }
效果匹配说明
针对示例中解绑值为“C1”节点的场景:
- 原结构中C1是B1的子节点,C1下挂载D1、D2两个子节点
- 执行
c1Node.unbind()后:- C1从B1的子节点集合中移除
- D1、D2的父引用从C1重定向到B1,并加入B1的子节点集合
- 此时执行原DFS遍历打印,C1不会再出现在遍历序列中,D1、D2会直接作为B1的子节点被访问,完全匹配题目给出的预期打印结果
注:由于原有代码中子节点集合使用
HashSet存储,迭代顺序不固定,遍历顺序的随机差异不影响功能正确性。
测试验证步骤
- 调用原有
createTree()方法构建初始测试树 - 通过DFS遍历定位到值为“C1”的节点实例
- 调用该节点的
unbind()方法执行解绑 - 再次运行原有
printDfs()方法,即可验证解绑效果
内容的提问来源于stack exchange,提问作者Reuven Eliezer
相关产品推荐
相关产品推荐

