1、没有子节点直接删除就可以
2、如果待删除的节点只有一个子节点,那么直接删除,并用其他节点顶替他
3、如果待删除的节点有两个节点,这种情况就比较复杂,首先找出它的后续节点,处理后续节点与待删除节点的关系,然后在处理后续节点的子节点和被删除节点的子节点之间的关系
import java.util.Arrays; class BinarytTree<T extends Comparable<T>> { private class Node { // 存放Comparable,比较大小 private Comparable<T> data; //父节点 private Node parent; //左子树 private Node left; //右子树 private Node right; //构造方法负责数据的存储 public Node(Comparable<T> data) { this.data = data; } //适当位置存储 public void addNode(Node newNode) { //比当前节点小 if (newNode.data.compareTo((T) this.data) <= 0) { //没有左子树 if (this.left == null) { //保存左子树 this.left = newNode; //保存父节点 newNode.parent = this; } else { //继续向左判断,继续向下判断 this.left.addNode(newNode); } } else {//比根节点数据大 if (this.right == null) { //保存右子树 this.right = newNode; newNode.parent = this; } else { //继续向右判断,继续向下判断 this.right.addNode(newNode); } } } //打印树结构 public void toArrayNode() { //没有左子树 递归调用 if (this.left != null) { this.left.toArrayNode(); } BinarytTree.this.returnData[BinarytTree.this.foot++] = this.data; if (this.right != null) { this.right.toArrayNode(); } } //检查父节点 public boolean containsNode(Comparable<T> data) { if (data.compareTo((T) this.data) == 0) { return true; } else if (data.compareTo((T) this.data) < 0) { if (this.left != null) { return this.left.containsNode(data); } else { return false; } } else { if (this.right != null) { return this.right.containsNode(data); } else { return false; } } } //获取要删除的节点对象 public Node getRemovNode(Comparable<T> data) { // if (data.compareTo((T) this.data) == 0) { return this;//找到了 } else if (data.compareTo((T) this.data) < 0) { if (this.left != null) { return this.left.getRemovNode(data); } else { return null; } } else { if (this.right != null) { return this.right.getRemovNode(data); } else { return null; } } } } //所有数据的获取->中序遍历 //*********二叉树操作***********// //注意根节点 是写在哪里的 private Node root; private int count; private Object[] returnData; private int foot = 0;//脚标 public void add(Comparable<T> data) { if (data == null) { throw new NullPointerException("保存数据为空"); } //所有数据没有节点关系的匹配 那么一定将其包装在Node类中 Node newNode = new Node(data); //保存节点 if (this.root == null) { //现在没有根节点,则第一个节点作为根节点 this.root = newNode; } else { //保存到合适的节点 this.root.addNode(newNode); } //计数 this.count++; } //删除处理 public void remove(Comparable<T> data) { //得到被删除这个数据的父节点,左右两颗子树 Node current = this.root.getRemovNode(data); if (current != null) { //没有任何子节点 if (current.left == null && current.right == null) { //父节点断开引用 检测他是那颗树 断开父节点的 左右子树连接 if (current.parent.left == current) { current.parent.left = null; } else { current.parent.right = null; } current.parent = null; } else if (current.left != null && current.right == null) { //左子树不为空 那么让他的左子树等于他的父节点的左子树 他的父子树等于他左子树的父子树 更改了 //父节点的指向 不在指向此位置 current.parent.left = current.left; current.left.parent = current.parent; } else if (current.left == null && current.right != null) { //右子树不为空 那么让他的右子树等于他的父节点的右子树 他的父子树等于他右子树的父子树 更改了 //父节点的指向 不在指向此位置 current.parent.right = current.right; current.right.parent = current.parent; } else { //此方式适用于左子树 /*两边都有节点 找被删除的数据中的右子树的最左节点 此数据A(moveNode) 替换要被删除的数据 数据A(moveNode)的父级的left不再有指向 被删除的数据(current)的左子树的parent 指向 A(moveNode) 被删除的数据(current)的parent的left 指向 A(moveNode) A(moveNode)左子树指向被删除的数据(current)的左子树 A(moveNode)的右子树指向被删除的数据(current)的右子树 current就是被删除的节点*/ Node moveNode = current.right; if (moveNode.left != null) { while (moveNode.left != null) { //还有左边的节点 moveNode = moveNode.left;//一直向左找 } //确定删除节点的最左边的最小节点 current.parent.left = moveNode; moveNode.parent.left = null; moveNode.left = current.left; moveNode.parent = current.parent; moveNode.right = current.right; }else { current.parent.left = moveNode; moveNode.left = current.left; current.left.parent = moveNode; moveNode.parent = current.parent; } } this.count--; } } public boolean contains(Comparable<T> data) { if (this.count == 0) { return false; } return this.root.containsNode(data); } //以对象数组的形式返回全部数据 没有数据返回Null public Object[] toArray() { if (this.count == 0) { return null; } //保存长度为数组长度 this.returnData = new Object[this.count]; this.foot = 0;//脚标清零 this.root.toArrayNode(); return this.returnData; } } class Persons implements Comparable<Persons> { private String name; private int age; public Persons(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "姓名:'" + name + '\'' + ", 年龄:'" + age + '\''; } @Override public int compareTo(Persons o) { return this.age - o.age; } } public class demotree { public static void main(String args[]) { BinarytTree<Persons> btree = new BinarytTree<>(); btree.add(new Persons("小强-80", 80)); btree.add(new Persons("小强-50", 50)); btree.add(new Persons("小强-60", 60)); btree.add(new Persons("小强-30", 30)); btree.add(new Persons("小强-90", 90)); btree.add(new Persons("小强-10", 10)); btree.add(new Persons("小强-55", 55)); btree.add(new Persons("小强-70", 70)); btree.add(new Persons("小强-85", 85)); btree.add(new Persons("小强-95", 95)); btree.remove(new Persons("小强-90", 90)); /* btree.remove(new Persons("小强-70", 70)); btree.remove(new Persons("小强-85", 85)); btree.remove(new Persons("小强-95", 95));*/ System.out.println(Arrays.toString(btree.toArray())); //System.out.println(btree.contains(new Persons("小强-30", 30))); } }
结果
[ 姓名:'小强-10', 年龄:'10', 姓名:'小强-30', 年龄:'30', 姓名:'小强-55', 年龄:'55', 姓名:'小强-60', 年龄:'60', 姓名:'小强-70', 年龄:'70', 姓名:'小强-80', 年龄:'80', 姓名:'小强-85', 年龄:'85', 姓名:'小强-90', 年龄:'90', 姓名:'小强-95', 年龄:'95' ]
右子树懒得写了...下次补上