二叉树删除节点
让deleNode节点的左子节点直接顶替deleNode,“让deleNode节点的左子节点的最大节点“指向“delete节点的右子节点”
这两种方法有什么不一样吗,都能实现二叉树的节点删除。
标题下面的是第二种方法
package com.tjetc.Tree;
import com.tjetc.Tree.printer.BinaryTreeInfo;
public class BinarySearchTree implements BinaryTreeInfo {
//根节点
private Node root;
//节点数量
private int size;
public void add(int element) {
Node newNode = new Node(element);
if (root == null) {
//如果root是null,那么newNode给root
root = newNode;
//size数量+1
size++;
} else {
//从根节点循环搜索树的节点的值跟传入的element比大小,如果节点的值大于element值,向节点的左子节点搜索,反之向右子节点搜索
//最终搜索到左子节点或右子节点为空为止
Node currentNode = root;
Node parent = root;
while (currentNode != null) {
//当前节点赋值给parent
parent = currentNode;
if (currentNode.element > element) {
//左子节点搜索
currentNode = currentNode.left;
} else if (currentNode.element < element) {
//右子节点搜索
currentNode = currentNode.right;
} else {
//直接返回不执行
return;
}
}
newNode.setPreNode(parent);
//newNOde放到parent的左边还是右边
if (parent.element > element) {
//放到左子节点
parent.left = newNode;
} else {
//放到右子节点
parent.right = newNode;
}
size++;
}
}
/**
* 检索二叉树删除节点
* <p>
* 思路1.根据要删除的元素值,从根节点检索到对应的Node节点
* 2.要删除的节点分三种情况
* (1)要删除的是叶子节点直接删除
* (2)要删除的节点右左子节点或者右子节点一个分支,需要判断
* deleteNOde下一个节点是parent左子节点还是右子节点,
* (3)要删除的节点右左子节点和右子节点,找出deleteNode的
* 左子树的最大节点值(右子树的最小值),把最大节点值覆盖要
* 删除的节点值,又回到了(1)或者(2)
*/
public void deleteNode(int element) {
Node currentNode = root;
while (currentNode.element != element) {
//当前节点赋值给parent
if (currentNode.element > element) {
//左子节点搜索
currentNode = currentNode.left;
} else if (currentNode.element < element) {
//右子节点搜索
currentNode = currentNode.right;
} else {
//直接返回不执行
return;
}
}
Node preNode = currentNode.preNode;
if (preNode == null) {
root = root.right;
return;
}
//要删除的是叶子节点
if (currentNode.left == null && currentNode.right == null) {
if (preNode.element > currentNode.element) {
preNode.left = null;
} else {
preNode.right = null;
}
//要删除的是有左子节点或者右子节点的节点;
} else if (currentNode.left == null || currentNode.right == null) {
//要删除的节点有左子节点
if (currentNode.right == null) {
//判断要删除的节点是父节点的左子节点还是右子节点
if (currentNode.element > preNode.element) {
preNode.right = currentNode.left;
} else {
preNode.left = currentNode.left;
}
}
//要删除的节点有右子节点
if (currentNode.left == null) {
//判断要删除的节点是父节点的左子节点还是右子节点
if (currentNode.element < preNode.element) {
preNode.left = currentNode.right;
} else {
preNode.right = currentNode.right;
}
}
//要删除的节点同时有左子节点和右子节点
} else {
//找左子树最大的覆盖要删除的节点
Node leftChildMaxNode = currentNode.left;
while (leftChildMaxNode.right != null) {
leftChildMaxNode = leftChildMaxNode.right;
}
preNode = leftChildMaxNode.preNode;
currentNode.element = leftChildMaxNode.element;
preNode.right = leftChildMaxNode.left;
}
size--;
}
//先序遍历
public void preorder() {
//顺序根左右
preorderTravelsal(root);
}
private void preorderTravelsal(Node node) {
if (node == null) {
return;
}
System.out.println(node.element); //根
preorderTravelsal(node.left); //左
preorderTravelsal(node.right); //右
}
//中序便利
public void inorder() {
//左根右
inorderTravelsal(root);
}
public void inorderTravelsal(Node node) {
if (node == null) {
return;
}
inorderTravelsal(node.left);
System.out.println(node.element);
inorderTravelsal(node.right);
}
//后序遍历
public void postorder() {
//左右根
postorderTravelsal(root);
}
public void postorderTravelsal(Node node) {
if (node == null) {
return;
}
postorderTravelsal(node.left);
postorderTravelsal(node.right);
System.out.println(node.element);
}
/**
* 返回根节点
*
* @return
*/
@Override
public Object root() {
return root;
}
/**
* 打印树需要返回node对应的左子节点
*
* @param node
* @return
*/
@Override
public Object left(Object node) {
return ((Node) node).left;
}
/**
* 打印树需要的node对应的右子节点
*
* @param node
* @return
*/
@Override
public Object right(Object node) {
return ((Node) node).right;
}
@Override
public Object string(Object node) {
return ((Node) node).element;
}
class Node {
/**
* 保存数据
*/
private int element;
/**
* 左子节点
*/
private Node left;
/**
* 右子节点
*/
private Node right;
private Node preNode;
public Node getPreNode() {
return preNode;
}
public void setPreNode(Node preNode) {
this.preNode = preNode;
}
public Node(int element) {
this.element = element;
}
public int getElement() {
return element;
}
public void setElement(int element) {
this.element = element;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
}