删除二叉树中的指定节点可分为几种情况:
(1)若指定节点即无左孩子,也无右孩子,则可直接删除节点
(2)若指定节点左孩子为空,含有右孩子,则将其右孩子代替要删除的节点
(3)若指定节点右孩子为空,含有左孩子,则将其左孩子代替要删除的节点
(4)若指定节点既有左孩子,又有右孩子,分为:1.右孩子非空情况下,只需查找到其右子树的最小节点代替要删除的节点,2.若右孩子非空,则应找到该节点在全树的后继节点代替要删除的节点。
Java具体实现代码如下:
/** *在查找二叉树中删除给定节点 */ public void deleteNode(int data) throws Exception { TreeNode node=searchNode(data); if (node==null){ throw new Exception("该节点不存在!"); }else{ delete(node); } } /** * 删除指定节点 * @param node * @throws Exception */ private void delete(TreeNode node) throws Exception { if (node==null){ throw new Exception("删除节点不存在!"); }else{ TreeNode parent=node.parent; /*删除节点既没有左孩子也没有右孩子*/ if (node.leftChild==null&&node.rightChild==null){ if (parent.leftChild==node){ parent.leftChild=null; }else{ parent.rightChild=null; } return; } /*删除节点有左孩子,但是没有右孩子*/ if (node.leftChild!=null&&node.rightChild==null){ if (parent.leftChild==node){ parent.leftChild=node.leftChild; }else{ parent.rightChild=node.leftChild; } return; } /*删除节点有右孩子,但是没有左孩子*/ if (node.leftChild==null&&node.rightChild!=null){ if (parent.leftChild==node){ parent.leftChild=node.rightChild; }else{ parent.rightChild=node.rightChild; } return; } /*删除节点左右孩子都有*/ TreeNode next=getNextNode(node); delete(next); node.data=next.data; } } /** * 获取指定节点的后继节点 * @param node * @return */ private TreeNode getNextNode(TreeNode node) { if (node==null){ return null; }else{ if (node.rightChild!=null){ /*如果节点的右孩子非空,则找到该节点右子树的最小节点*/ return getMinNode(node.rightChild); }else { /*如果右节点为空,则寻找该节点在全树的后继节点*/ TreeNode parent=node.parent; /*如果节点的父节点非空,且节点是父节点的右孩子,则继续遍历*/ while(parent!=null&&parent.rightChild==node){ node=parent; parent=parent.parent; } return parent; } } } /*查找树的值域最小的节点,即一直遍历左子树的左孩子*/ private TreeNode getMinNode(TreeNode node) { if (node==null){ return null; }else{ while(node.leftChild!=null){ node=node.leftChild; } } return node; } /** * 查找给定的二叉树节点 * @param key * @return */ private TreeNode searchNode(int key) { TreeNode node=root; if (node==null){ return null; }else{ while(node!=null&&key!=node.data){ if (key<node.data){ node=node.leftChild; }else{ node=node.rightChild; } } } return node; }