如何高效使用BiRefNet:高分辨率二分割图像分割的完整指南
2026/6/9 14:48:33
前置知识:二叉树的构建和增删改查-CSDN博客
二叉树的删除操作是指在二叉树中移除某个特定节点,同时需要保持二叉树的基本性质不变。删除操作比插入操作更为复杂,因为需要考虑被删除节点的子树如何重新连接到树上。
5 / \ 3 7删除后:3 \ 75 / \ 3 8 \ 7删除后:5 / \ 7 8这是最复杂的情况,通常有以下两种处理方法:
示例:删除节点5
5 / \ 3 8 / \ / \ 2 4 7 9使用后继节点方法:
结果:
7 / \ 3 8 / \ / \ 2 4 9图示操作可见1.2
情况一:targetNode是parentNode的左子树
情况二:targetNode是parentNode的右子树
public TreeNode findTarget(TreeNode root, Integer target) { if (root == null || target == null) return null; TreeNode cur = root; while (cur != null) { if (cur.data.equals(target)) { return cur; } else if (cur.data < target) { cur = cur.rChild; } else { cur = cur.lChild; } } return null; }3.2 创建方法用于去找要删除的节点的父节点
public TreeNode findParent(TreeNode root,Integer target){ if(root==null){ return null; } if((root.lChild!=null) && (root.lChild.data.equals(target))|| (root.rChild!=null) && (root.rChild.data.equals(target))){ return root; }else { if(root.lChild!=null && target<root.data){ return findParent(root.lChild,target); }else if(root.rChild!=null && target>root.data){ return findParent(root.rChild,target); }else { return null; } } }public int findRightTreeMin(TreeNode node){ while (node.lChild!=null){ node = node.lChild; } int min = node.data; delete(root,min); return min; }if(root.lChild==null && root.rChild==null){//删除的是叶子节点 root=null; return; }if (targetNode.lChild == null && targetNode.rChild == null) { // 叶子节点 // 确定targetNdoe 是parentNode的左子节点还是右子节点 if (parentNode.lChild != null && parentNode.lChild.data.equals(target)) { parentNode.lChild = null; }else if (parentNode.rChild != null && parentNode.rChild.data.equals(target)) { parentNode.rChild = null; }if (targetNode.lChild != null && targetNode.rChild != null) { // 两个子节点的节点 int min = findRightTreeMin(targetNode.rChild);//寻找右子树最小的节点 targetNode.data = min; }if(parentNode.lChild!=null && parentNode.lChild.data.equals(target)){ // targetNode是parentNode的左子节点 if(targetNode.lChild!=null){//删除的是有子节点的节点 parentNode.lChild = targetNode.lChild; }else if(targetNode.rChild!=null){//删除的是有子节点的节点 parentNode.lChild = targetNode.rChild; } }else if(parentNode.rChild!=null && parentNode.rChild.data.equals(target)){ // targetNode是parentNode的右子节点 if(targetNode.lChild!=null){//删除的是有子节点的节点 parentNode.rChild = targetNode.lChild; }else if(targetNode.rChild!=null){//删除的是有子节点的节点 parentNode.rChild = targetNode.rChild; } }//删除节点 public void delete(TreeNode root,Integer target){ if (root==null){ return; } //2.万一要删除的节点只有一个节点 if(root.lChild==null && root.rChild==null){//删除的是叶子节点 root=null; return; } //1.找要删除的节点 TreeNode targetNode = findTarget(root,target); if(targetNode==null){ return; } //3.找到父节点 TreeNode parentNode = findParent(root,target); // 请你进行讲解 if (targetNode.lChild == null && targetNode.rChild == null) { // 叶子节点 // 确定targetNdoe 是parentNode的左子节点还是右子节点 if (parentNode.lChild != null && parentNode.lChild.data.equals(target)) { parentNode.lChild = null; }else if (parentNode.rChild != null && parentNode.rChild.data.equals(target)) { parentNode.rChild = null; } } else if (targetNode.lChild != null && targetNode.rChild != null) { // 两个子节点的节点 int min = findRightTreeMin(targetNode.rChild);//寻找右子树最小的节点 targetNode.data = min; } else { // 只有一个子节点的节点 // 确定targetNdoe 是parentNode的左子节点还是右子节点 if(parentNode.lChild!=null && parentNode.lChild.data.equals(target)){ // targetNode是parentNode的左子节点 if(targetNode.lChild!=null){//删除的是有子节点的节点 parentNode.lChild = targetNode.lChild; }else if(targetNode.rChild!=null){//删除的是有子节点的节点 parentNode.lChild = targetNode.rChild; } }else if(parentNode.rChild!=null && parentNode.rChild.data.equals(target)){ // targetNode是parentNode的右子节点 if(targetNode.lChild!=null){//删除的是有子节点的节点 parentNode.rChild = targetNode.lChild; }else if(targetNode.rChild!=null){//删除的是有子节点的节点 parentNode.rChild = targetNode.rChild; } } }删除二叉树中的节点需要根据节点类型(叶子节点、单子节点、双子节点)采取不同策略,同时保持二叉树的特性(如二叉搜索树的顺序性)。
直接移除该节点,并将其父节点的对应子节点指针置空。无需调整树结构。
将该节点的唯一子节点提升到被删除节点的位置,保持树的连通性。
对于有两个子节点的节点,通常采用以下两种方法之一:
方法1:前驱替换法找到左子树的最大节点(前驱),用其值替换待删除节点,然后递归删除前驱节点。
方法2:后继替换法找到右子树的最小节点(后继),用其值替换待删除节点,然后递归删除后继节点。