Java 二叉排序树的结点删除
假设被删结点为p,其双亲节点为f。
共有三种情况:
1.p为叶子结点,删去p,并修改f的孩子域;
2.p只有左子树或者只有右子树,令p.lchild或p.rchild直接成为f的子树;
3.p的左右子树均不为空;
1.删除结点
//删除结点
public void delNode(int value) {
if(root == null) {
return;
}
else {
//找到要删除的结点 targetNode
BSTNode targetNode = search(value);
//如果没有找到要删除的结点
if(targetNode == null) {
return;
}
//找到要删除的结点targetNode
//去找到targetNode的父结点
BSTNode parent = searchParent(value);
//删除叶子结点
if(targetNode.getLeft() == null && targetNode.getRight() == null) {
//如果既是叶子节点又是根节点,则整棵树只有一个根结点,它无父结点
//找到该结点且该结点无父结点——>根节点——>删除根结点
if(parent==null){
root = null;
return;
}
//有父结点:判断targetNode 是父结点的左子结点,还是右子结点
else{
//是左子结点
if(parent.getLeft()!= null && parent.getLeft().getValue() == value) {
parent.setLeft(null);
}
//是由子结点
else if (parent.getRight() != null && parent.getRight().getValue() == value) {
parent.setRight(null);
}
}
}
//删除有两棵子树的结点
else if (targetNode.getLeft() != null && targetNode.getRight() != null) {
int minVal = delRightTreeMin(targetNode.getRight());
targetNode.setValue(minVal);
}
// 删除只有一棵子树的结点
else {
//如果要删除的结点有左子结点
if(targetNode.getLeft() != null) {
if(parent != null) {
//如果 targetNode 是 parent 的左子结点
if(parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getLeft());
}
// targetNode 是 parent 的右子结点
else {
parent.setRight(targetNode.getLeft());
}
}
else {
root = targetNode.getLeft();
}
}
//如果要删除的结点有右子结点
else {
if(parent != null) {
//如果 targetNode 是 parent 的左子结点
if(parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getRight());
}
//如果 targetNode 是 parent 的右子结点
else {
parent.setRight(targetNode.getRight());
}
}
else{
root = targetNode.getRight();
}
}
}
}
}
2.完整代码;
public class BinarySortTreeDemo {
public static void main(String[] args) {
BinarySortTree bst=new BinarySortTree();
int []arr={7,3,10,12,5,1,9,0};
//循环添加结点到二叉排序树
for(int tmp:arr){
bst.add(new BSTNode(tmp));
}
/*//中序遍历
bst.infixOrder();
for(int tmp:arr){
System.out.println(tmp);
System.out.println(bst.search(tmp));
System.out.println(bst.searchParent(tmp));
}*/
bst.delNode(1);
bst.infixOrder();
}
}
class BinarySortTree{
private BSTNode root;
public BinarySortTree() {
super();
// TODO Auto-generated constructor stub
}
public BinarySortTree(BSTNode root) {
super();
this.root = root;
}
public BSTNode getRoot() {
return root;
}
public void setRoot(BSTNode root) {
this.root = root;
}
//添加结点的方法
public void add(BSTNode node){
if(root==null){
root=node;
}
else{
root.add(node);
}
}
//中序遍历
public void infixOrder(){
if(root==null){
System.out.println("该二叉树为空");
}
else{
root.infixOrder();
}
}
//查找要删除的结点
public BSTNode search(int value){
if(root==null){
System.out.println("该二叉树为空");
}
return root.search(value);
}
//查找要删除的结点的父节点
public BSTNode searchParent(int value){
if(root==null){
System.out.println("该二叉树为空");
}
return root.searchParent(value);
}
//删除结点
public void delNode(int value) {
if(root == null) {
return;
}
else {
//找到要删除的结点 targetNode
BSTNode targetNode = search(value);
//如果没有找到要删除的结点
if(targetNode == null) {
return;
}
//去找到targetNode的父结点
BSTNode parent = searchParent(value);
//删除叶子结点
if(targetNode.getLeft() == null && targetNode.getRight() == null) {
//如果既是叶子节点又是根节点,则整棵树只有一个根结点,它无父结点
//找到该结点且该结点无父结点——>根节点——>删除根结点
if(parent==null){
root = null;
return;
}
//有父结点:判断targetNode 是父结点的左子结点,还是右子结点
else{
//是左子结点
if(parent.getLeft()!= null && parent.getLeft().getValue() == value) {
parent.setLeft(null);
}
//是由子结点
else if (parent.getRight() != null && parent.getRight().getValue() == value) {
parent.setRight(null);
}
}
}
//删除有两棵子树的结点
else if (targetNode.getLeft() != null && targetNode.getRight() != null) {
int minVal = delRightTreeMin(targetNode.getRight());
targetNode.setValue(minVal);
}
// 删除只有一棵子树的结点
else {
//如果要删除的结点有左子结点
if(targetNode.getLeft() != null) {
if(parent != null) {
//如果 targetNode 是 parent 的左子结点
if(parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getLeft());
}
// targetNode 是 parent 的右子结点
else {
parent.setRight(targetNode.getLeft());
}
}
else {
root = targetNode.getLeft();
}
}
//如果要删除的结点有右子结点
else {
if(parent != null) {
//如果 targetNode 是 parent 的左子结点
if(parent.getLeft().getValue() == value) {
parent.setLeft(targetNode.getRight());
}
//如果 targetNode 是 parent 的右子结点
else {
parent.setRight(targetNode.getRight());
}
}
else{
root = targetNode.getRight();
}
}
}
}
}
/**
*
* @param node 传入的结点(当做二叉排序树的根结点)
* @return 返回的 以node 为根结点的二叉排序树的最小结点的值
*/
public int delRightTreeMin(BSTNode node) {
BSTNode target = node;
//循环的查找左子节点,就会找到最小值
while(target.getLeft() != null) {
target = target.getLeft();
}
//这时 target就指向了最小结点
//删除最小结点
delNode(target.getValue());
return target.getValue();
}
}
class BSTNode{
private int value;
private BSTNode left;
private BSTNode right;
public BSTNode() {
super();
}
public BSTNode(int value) {
super();
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BSTNode getLeft() {
return left;
}
public void setLeft(BSTNode left) {
this.left = left;
}
public BSTNode getRight() {
return right;
}
public void setRight(BSTNode right) {
this.right = right;
}
@Override
public String toString() {
return "BSTNode [value=" + value + "]";
}
/**
* 向二叉排序树添加结点
* @param node
*/
public void add(BSTNode node){
if(node==null){
return;
}
if(node.value<this.value){
if(this.left==null){
this.setLeft(node);
}
else{
this.left.add(node);
}
}
else{
if(this.right==null){
this.setRight(node);
}
else{
this.right.add(node);
}
}
}
//中序遍历
public void infixOrder(){
if(this.getLeft()!=null){
this.left.infixOrder();
}
System.out.println(this);
if(this.getRight()!=null){
this.right.infixOrder();
}
}
//查找要删除结点
public BSTNode search(int value){
if(this.value==value){
return this;
}
//左子树查找
if(value<this.value){
if(this.left==null){
return null;
}
else{
return this.left.search(value);
}
}
//右子树查找
else{
if(this.right==null){
return null;
}
else{
return this.right.search(value);
}
}
}
//查找要删除结点的父节点
public BSTNode searchParent(int value){
if((this.left!=null&&this.left.value==value)||(this.right!=null&&this.right.value==value)){
return this;
}
//左子树查找
if(value<this.value){
if(this.left==null){
return null;
}
else{
return this.left.searchParent(value);
}
}
//右子树查找
else{
if(this.right==null){
return null;
}
else{
return this.right.searchParent(value);
}
}
}
}