删除排序二叉树的节点

    xiaoxiao2021-03-25  58

    LeetCode问题描述:

    Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.

    Basically, the deletion can be divided into two stages:

    Search for a node to remove.If the node is found, delete the node.

    Note: Time complexity should be O(height of tree).

    Example:

    root = [5,3,6,2,4,null,7] key = 3 5 / \ 3 6 / \ \ 2 4 7 Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the following BST. 5 / \ 4 6 / \ 2 7 Another valid answer is [5,2,6,null,4,null,7]. 5 / \ 2 6 \ \ 4 7

    题目大意是说给定某一个排序二叉树(BST)和一个Key值,要求删除此排序二叉树中与Key值相等的节点,之后返回此BST的根节点。 分析如下:

    一、查找节点:

    这一步是最基础的,一般大家会想到利用BST的性质直接进行查找,但是在这里可能会有点问题(后面会讲到)。

    二、删除节点:

    分三种情况——该节点无子节点、该节点有1个子节点、该节点有2个子节点。

    ①无子节点: 在这种情况下,我们这需做一个判断——如果该节点为根节点,则直接返回null; 否则,对其父节点中该节点赋值null,并返回root(根节点)。

    ②有1个子节点: 判断——如果该节点为root节点,直接返回其子节点;否则,对其父节点中该节点赋值为该节点的子节点,并返回root。

    ③有2个子节点: 这种情况最复杂,先找到该节点右子树的最小节点,并将此最小节点与该节点进行值交换,然后删除找到的这个最小节点。 注:这里递归删除时会有一些问题,因为虽然原二叉树是BST,但将节点的值进行交换后,顺序改变,就不再是BST了,所以一中不应该使用BST的查找算法,而应该采用遍历查找。

    实现代码如下(Java):

    class TreeNode{ int val;//节点值 TreeNode left; TreeNode right; TreeNode(int x){ this.val = x; } } class Solution{ //输出第level层的节点的值 public int showTreeValueAtLevel(TreeNode node , int level){ if(level < 0) return 0;//如果node为空或者level<0,直接结束 else if(node == null){ System.out.print("null "); return 0; } else if(level == 0 && node != null){ System.out.print(node.val+" "); return 1;//level == 0时即为找到了此节点 } return showTreeValueAtLevel(node.left, level-1)+showTreeValueAtLevel(node.right, level-1); } public void levelTravelsal(TreeNode node){ int i;//遍历的层数 for(i = 0;;i++){ if(showTreeValueAtLevel(node, i)==0)//终止遍历条件 break; System.out.println(); } } public TreeNode deleteNode(TreeNode root, int key) { if(root == null) return null; TreeNode father = searchFatherNode(root, key); TreeNode desNode;//目标节点 desNode = getDesNode(root, father, key); System.out.println("father:"+father); if(desNode == null){ return root; }else{ if(desNode.left == null && desNode.right == null){ //目标节点存在且无子节点 if(desNode == root) return null; else if(father.left == desNode) father.left = null; else father.right = null; }else if(desNode.left != null && desNode.right == null ){ //目标节点存在且只有左节点 if(desNode == root)//如果是根结点,直接返回其子节点 return desNode.left; desNode.val = desNode.left.val; if(father.left == desNode) father.left = desNode.left; else father.right = desNode.left; }else if(desNode.right != null && desNode.left == null){ //目标节点存在且只有右节点 if(desNode == root)//如果是根结点,直接返回其子节点 return desNode.right; desNode.val = desNode.right.val; if(father.left == desNode) father.left = desNode.right; else father.right = desNode.right; }else{ //目标节点有左右子节点 // System.out.println("currDesNode:"+desNode.val); TreeNode minNode = getMinNode(desNode.right); // System.out.println("minNode:"+minNode.val); Swap(desNode, minNode); return deleteNode(root, key); } return root; } } //交换两节点的值 public void Swap(TreeNode node1, TreeNode node2){ int temp = node1.val; node1.val = node2.val; node2.val = temp; } //从根结点出发,返回最小的节点 public TreeNode getMinNode(TreeNode root){ if(root.left != null) return getMinNode(root.left); return root; } //找出符合条件的节点的父节点 public TreeNode searchFatherNode(TreeNode root, int key){ if(root == null) return null; if(root.left != null && root.left.val == key) return root; else if(root.right != null && root.right.val == key) return root; //继续找 TreeNode resNode; if(root.left != null){ resNode = searchFatherNode(root.left, key); if(resNode != null) return resNode; } if(root.right != null){ resNode = searchFatherNode(root.right, key); if(resNode != null) return resNode; } return null; } public TreeNode getDesNode(TreeNode root,TreeNode father, int key){ if(father == null){ if(root.val == key)//目标节点就是根结点 return root; else return null;//目标节点不存在 }else{ //如果father不为空,则目标节点一定存在; if(father.left != null && father.left.val == key) return father.left; else return father.right; } } }
    转载请注明原文地址: https://ju.6miu.com/read-36108.html

    最新回复(0)