相对于增查改,二叉树的删除是较为复杂的,必须保证删除后所有节点大于其左节点,小于其右节点。
删除节点分为几种情况:
1.删除的节点为叶子节点:直接删除。
2.删除的节点只存在左子树或右子树:删除节点的父节点直接指向子树节点。
3.删除的节点同时存在左子树和右子树:将删除节点的左子树的最右节点或右子树的最左节点替换删除节点,同时删除替换节点,再将删除节点指向子树节点。
示例分析:
1.删除的节点为叶子节点:直接删除。
删除叶子节点62,直接将60的右子树置空即可。
2.删除的节点只存在左子树或右子树:删除节点的父节点直接指向子树节点。
删除60节点,将50节点直接指向60节点的子节点。
3.删除的节点同时存在左子树和右子树:将删除节点的左子树的最右节点或右子树的最左节点替换删除节点,同时删除替换节点,再将删除节点指向子树节点。
将60左子树最右节点替换删除节点。
Java代码实现:
package TwoTree;
import java.util.Stack;
public class TwoTree {
public int value;
public TwoTree parent;
public TwoTree left;
public TwoTree right;
//构造函数
public TwoTree() {};
public TwoTree(int value) {
this.value=value;
}
@Override
public String toString() {
return "TwoTree [value=" + value + ", left=" + left + ", right=" + right + "]";
}
//添加节点
public TwoTree insert(TwoTree root,TwoTree p) {
if(root==null) {
root=p;
root.parent=null;
return root;
}
TwoTree temp=new TwoTree();
temp=root;
while(temp!=null) {
if(temp.value<p.value) {
if(temp.right!=null) {
temp=temp.right;
}
else {
temp.right=new TwoTree();
temp.right.value=p.value;
temp.right.parent=temp;
break;}
}
if(temp.value>p.value) {
if(temp.left!=null) {
temp=temp.left;
}
else{
temp.left=new TwoTree();
temp.left.value=p.value;
temp.left.parent=temp;
break;
}
}
}
return root;
}
//遍历节点
public void Bst(TwoTree root) {
if(root!=null) {
Bst(root.left);
System.out.print(root.value+" ");
Bst(root.right);
}
}
//查找节点
public TwoTree Select(TwoTree root,int value) {
TwoTree flag=new TwoTree();
Stack<TwoTree> stack=new Stack<TwoTree>();
while(!stack.empty()||root!=null)
{
if(root!=null) {
if(root.value==value)
{
flag=root;
}
stack.push(root);
root=root.left;
}
else {
root=stack.pop();
if(root.value==value)
{
flag=root;
}
root=root.right;
}
}
return flag;
}
//删除节点
public void Delete(TwoTree root,int value) {
TwoTree temp=new TwoTree();
temp=Select(root, value);
if(temp.value==0) {
System.out.println("你要删除的数值"+value+"不存在");
}
else {
TwoTree p=new TwoTree();
TwoTree node=new TwoTree();
TwoTree parent=new TwoTree();
p=p.Select(root, value); //p是要删除的结点
node=p;
if(p!=null) {
if(p.left!=null) {
p=node.left;
while(p.right!=null) {
p=p.right;
}
node.value=p.value;
if(node.left.right==null) {
node.left=p.left;
}
else{
p.parent.right=p.left;
}
}
else if(p.right!=null)
{
p=p.right;
node.value=p.value;
node.left=p.left;
node.right=p.right;
}
else {
if(p.equals(p.parent.left))
{
p.parent.left=null;
}
if(p.equals(p.parent.right))
{
p.parent.right=null;
}
}System.out.println("");
System.out.println("数据"+value+"删除成功");
}
}
}
//修改节点
public void Update(TwoTree root,int value,int update) {
TwoTree temp=new TwoTree();
temp=temp.Select(root, value);
if(temp.value==value) {
Delete(root,value);
TwoTree a= new TwoTree(update);
insert(root,a);
System.out.println("数据"+value+"成功更新成"+update);
}
else {
System.out.println("数据"+value+"更新失败");
}
}
}
package TwoTree;
public class TreeTest{
public static void main(String []args) {
TwoTree tt=new TwoTree();
tt.value=22;
int []a= {20,8,2,4,5,6,28,18,19,33,25,26};
for(int i=0;i<a.length;i++) {
TwoTree aa=new TwoTree(a[i]);
tt.insert(tt, aa);
}
System.out.println(tt);
tt.Delete(tt,28);
System.out.print(tt);
}
}