二叉树删除节点
在自己研究二叉树删除节点时,查网上资料时发现,网上大部分写的都是错的,主要错在当删除的节点既存在左子树,又存在右子树时,在中序遍历后获取后继节点后,大部分文章未考虑后继节点存在右子树的情况。
1.二叉树图
删除的节点有4种情况
- 叶子节点
- 只存在左节点
- 只存在右节点
- 既存在左节点,又存在右节点
以上四种情况分别如下处理:
1只需要将引用去除就行
2将删除节点的左子树,挂到父节点上
3将删除节点的右子树,挂到父节点上
4中序遍历树,获取删除节点的后继节点,即大于删除节点的最小节点,后继节点可以确定的是肯定不存在左子树,因为后继节点就是删除节点右子树里面最小的节点了,肯定不存在比他还小的节点。但是还是有可能存在右子树的 。处理逻辑就是将后继节点的值覆盖删除节点的值,并将后继节点的右子树挂到后继节点的父节点上。
下面就是硬干代码了,有个技巧,中序遍历出来的结果正好是升序排列的树,所以在删除后,可以通过打印中序遍历的结果,查看整棵树是不是正确的。
2.节点数据结构
public static class Node<T>{
private T data;
private Node<T> left;
private Node<T> right;
private Node<T> parent;
public Node(T data) {
this.data = data;
}
public T getData() {
return data;
}
public Node<T> getParent() {
return parent;
}
public void setParent(Node<T> parent) {
this.parent = parent;
}
public void setData(T data) {
this.data = data;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
}
3.先序创建树
// 创建树
public static Node<String> createTree(List<String> dataList,Node<String> parent){
Node<String> root = null;
if(!dataList.isEmpty()){
String data = dataList.remove(0);
if(data!=null){
root=new Node<>(data);
root.setParent(parent);
root.setLeft(createTree(dataList,root));
root.setRight(createTree(dataList,root));
}
}
return root;
}
//二叉树初始化
List<String> strings = new ArrayList<>();
strings.add("20");
strings.add(