对删除方法添加对根节点的支持
/**
* 删除指定数据的节点
*
* @param data
*/
public void delete(int data) {
if (mRoot == null ) { //根节点为空
return;
}
//标记根节点
boolean isRoot=false;
//接下来该找要删除的节点了
BinaryTreeNode deleteNode =null;
BinaryTreeNode parent=null;
if( mRoot.getData() == data){//判断是否是根
deleteNode=mRoot;
isRoot=true;
}else{
//在删除之前需要找到它的父亲
parent = searchParent(data);
if (parent == null) { //如果父节点为空,说明这个树是空树,没法删
return;
}
//接下来该找要删除的节点了
deleteNode = search(parent, data);
if (deleteNode == null) { //树中找不到要删除的节点
return;
}
}
//删除节点有 4 种情况
//1.左右子树都为空,说明是叶子节点,直接删除
if (deleteNode.getLeftChild() == null && deleteNode.getRightChild() == null) {
//删除节点
if(isRoot){ //根节点置空后直接返回
mRoot=null;
return;
}
//重置父节点的孩子状态,告诉他你以后没有这个儿子了
if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
parent.setLeftChild(null);
} else {
parent.setRightChild(null);
}
} else if (deleteNode.getLeftChild() != null && deleteNode.getRightChild() == null) {
//2.要删除的节点只有左子树,左子树要继承位置
if(isRoot){
mRoot=mRoot.getLeftChild();
return;
}
if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
parent.setLeftChild(deleteNode.getLeftChild());
} else {
parent.setRightChild(deleteNode.getLeftChild());
}
} else if (deleteNode.getRightChild() != null && deleteNode.getLeftChild() == null) {
//3.要删除的节点只有右子树,右子树要继承位置
if(isRoot){
mRoot=mRoot.getRightChild();
return;
}
if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
parent.setLeftChild(deleteNode.getRightChild());
} else {
parent.setRightChild(deleteNode.getRightChild());
}
} else {
//4.要删除的节点儿女双全,既有左子树又有右子树,需要选一个合适的节点继承,这里使用右子树中最左节点
BinaryTreeNode copyOfDeleteNode = deleteNode; //要删除节点的副本,指向继承节点的父节点
BinaryTreeNode heresNode = deleteNode.getRightChild(); //要继承位置的节点,初始为要删除节点的右子树的树根
//右子树没有左孩子了,他就是最小的,直接上位
if (heresNode.getLeftChild() == null) {
//上位后,兄弟变成了孩子
heresNode.setLeftChild(deleteNode.getLeftChild());
} else {
//右子树有左孩子,循环找到最左的,即最小的
while (heresNode.getLeftChild() != null) {
copyOfDeleteNode = heresNode; //copyOfDeleteNode 指向继承节点的父节点
heresNode = heresNode.getLeftChild();
}
//找到了继承节点,继承节点的右子树(如果有的话)要上移一位
copyOfDeleteNode.setLeftChild(heresNode.getRightChild());
//继承节点先继承家业,把自己的左右孩子变成要删除节点的孩子
heresNode.setLeftChild(deleteNode.getLeftChild());
heresNode.setRightChild(deleteNode.getRightChild());
}
if(isRoot){
mRoot=heresNode;
return;
}
//最后就是确认位置,让要删除节点的父节点认识新儿子
if (parent.getLeftChild() != null && parent.getLeftChild().getData() == data) {
parent.setLeftChild(heresNode);
} else {
parent.setRightChild(heresNode);
}
}
}