package com.example.datastructure.bst;
/**
* @description 二叉搜索树
* @Author tyw
* @Date 2023/10/23 20:13 星期一
*/
public class BinarySearchTree {
/**
* 树结构,我们知道根节点就可以了
* 定义树的根节点
*/
private TreeNode root;
/**
* 中序遍历树
*
* @return
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
inOrder(root, sb);
return sb.toString();
}
/**
* 递归下探
* @param node
* @param sb
*/
private void inOrder(TreeNode node, StringBuilder sb) {
if (node == null) {
return;
}
inOrder(node.left, sb);
sb.append(node.val).append("->");
inOrder(node.right, sb);
}
/**
* 添加操作(重要方法)
*
* @param val
*/
public boolean add(int val) {
//判断树是否为空
if (root == null) {
root = new TreeNode(val);
return true;
}
//定义比较的当前节点,比较的节点需要变化移动
TreeNode curr = root;
while (curr != null) {
if (curr.val < val) {
//新插入的数值大于根节点的数值,此时当前指针移动到root.rignt,如果右子节点为空,则用这个值创建一个节点,并让当前节点的right指针指向此节点。
if (curr.right == null) {
curr.right = new TreeNode(val);
return true;
}
curr = curr.right;
//继续开始比较,重复比较操作
} else if (curr.val > val) {
if (curr.left == null) {
curr.left = new TreeNode(val);
return true;
}
curr = curr.left;
} else {
//相等,不操作
return false;
}
}
return false;
}
/**
* 根据节点值查找
*
* @param val
* @return
*/
public TreeNode get(int val) {
//定义当前指针
TreeNode curr = root;
while (curr != null) {
if (curr.val < val) {
//去右子树查找
curr = curr.right;
} else if (curr.val > val) {
//去左子树查找
curr = curr.left;
} else {
//找到了
return curr;
}
}
//找不到,返回null
return curr;
}
/**
* 根据节点值删除节点
*/
public void remove(int val) {
//定义被删除的节点及它的父节点
TreeNode del = root;
TreeNode del_p = null;
while (del != null) {
if (val > del.val) {
del_p = del;
del = del.right;
} else if (val < del.val) {
del_p = del;
del = del.left;
} else {
//找到了
break;
}
}
if (del == null) {
return;
}
//根据不同情况来操作
//如果被删除的节点有两个子节点
if (del.left != null && del.right != null) {
//用被删除节点的右子树上的最小的节点来替换该删除的节点,然后,删除右子树上最小的节点(指向它的父节点的指针置为null)
//要先找到del它的右子树上最小的节点 ,如何找?移动指针法 定义最小节点 ,同事也要找到它的父节点 (在右子树上一直找左树上的节点)
TreeNode min = del.right;
TreeNode min_p = null;
while (min.left != null) {
//下探到下一层之前,记录父节点。
min_p = min;
min = min.left;
}
//用最小节点的值替换删除节点的值
del.val = min.val;
//真正要被删除的是这个最小的节点
del = min;
del_p = min_p;
}
//只剩两种情况了,要被删除的节点要么是叶子节点(没有子节点) 或者 有一个子节点
//找到要被删除节点的子节点
//定义一个子节点
TreeNode del_child = null;
if (del.left != null) {
del_child = del.left;
} else if ((del.right != null)) {
del_child = del.right;
}
//此时,del,del_p,del_child都有值了
//执行删除
if (del_p.left == del) {
del_p.left = del_child;
} else if (del_p.right == del) {
del_p.right= del_child;
}
//同时清空del指向的del_child
del.left = null;
del.right = null;
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
public int getVal() {
return this.val;
}
public TreeNode(int val) {
this.val = val;
}
public TreeNode(TreeNode left, int val, TreeNode right) {
this.left = left;
this.val = val;
this.right = right;
}
}
}
二叉搜索树java代码实现
于 2023-10-23 23:41:53 首次发布