二叉搜索树是一种特殊的二叉树,它的每一个节点都满足以下条件:
通过这种特殊的结构,二叉搜索树能够实现快速的插入、查找和删除操作。在二叉搜索树中,插入一个新节点的时间复杂度为 O(log n),查找或删除一个节点的时间复杂度同样为 O(log n),其中 n 是树中节点的数量。
因为其高效的查找和排序性质,二叉搜索树被广泛应用于各种领域,例如数据库索引、哈希表等数据结构的实现、模拟字典等应用中。
首先,需要确定要插入的节点在树中的位置。从根节点开始,与要插入的节点进行比较。
如果要插入的节点的值小于当前节点的值,那么就将其作为当前节点的左子节点。如果当前节点的左子节点为空,直接插入;如果不为空,将当前节点指向其左子节点,并继续执行第一步。
如果要插入的节点的值大于当前节点的值,那么就将其作为当前节点的右子节点。如果当前节点的右子节点为空,直接插入;如果不为空,将当前节点指向其右子节点,并继续执行第一步。
重复执行步骤 2 和步骤 3,直到找到合适的空位置插入节点。
首先,我们需要找到要删除的节点。从根节点开始,比较要删除的值与当前节点的值,根据大小关系选择向左子树或右子树移动,直到找到与要删除的值相等的节点。
找到要删除的节点后,有以下几种情况:
如果要删除的节点是叶节点(即没有左子树和右子树),直接将其从树中删除即可。
如果要删除的节点只有左子树或只有右子树,我们需要用它的子节点来替代要删除的节点。
如果要删除的节点既有左子树又有右子树,我们可以选择以下两种方式来替代要删除的节点:
a. 在右子树中找到最小的节点,即右子树中的最左叶节点。将该节点的值复制到要删除的节点,并将该节点删除。这样可以保持二叉搜索树的性质。
b. 在左子树中找到最大的节点,即左子树中的最右叶节点。将该节点的值复制到要删除的节点,并将该节点删除。同样,这样可以保持二叉搜索树的性质。
完成替代操作后,整个树的结构依然保持二叉搜索树的性质。
从根节点开始,将要查找的值与当前节点的值进行比较。
如果要查找的值等于当前节点的值,那么说明找到了目标节点,返回当前节点。
如果要查找的值小于当前节点的值,那么说明目标节点位于当前节点的左子树中。则将当前节点指向其左子节点,并继续执行第一步。
如果要查找的值大于当前节点的值,那么说明目标节点位于当前节点的右子树中。则将当前节点指向其右子节点,并继续执行第一步。
重复执行步骤 2、3 和 4,直到找到目标节点或者遍历完整个树(表示目标节点不存在)。
//创建节点类
private static class TreeNode{
T value;
TreeNode left;
TreeNode right;
//叶节点专属构造方法
public TreeNode(T value) {
this.value = value;
left = null;
right = null;
}
//默认构造方法
public TreeNode(T value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
}
public class TreeNodeTest>{
private TreeNode root;//创建一个根节点
public TreeNodeTest() {
root = null;
}
//指定一个根节点创建树
public TreeNodeTest(TreeNode root) {
this.root = root;
}
//插入节点
public void insert(T value){
root = insertRecursive(root, value);
}
//递归实现插入节点
private TreeNode insertRecursive(TreeNode root, T value) {
if (root == null){
return new TreeNode<>(value);
}
if (value.compareTo(root.value) < 0){
//小于此节点往此节点后面子节点继续找
root.left = insertRecursive(root.left,value);
}else if (value.compareTo(root.value) > 0){
root.right = insertRecursive(root.right,value);
}
return root;
}
// 查找最小值节点
private TreeNode findMin(TreeNode node) {
if (node.left == null) {
return node;
}
return findMin(node.left);
}
//查找节点
public boolean contains(T value) {
return containsRecursive(root, value);
}
//递归实现查找节点
private boolean containsRecursive(TreeNode root, T value) {
//递归的出口
if (root == null){
//意味着找到最后也没找到
return false;
}
if (value.compareTo(root.value) == 0){
return true;
}
if (value.compareTo(root.value) < 0){
return containsRecursive(root.left,value);
}else{
return containsRecursive(root.right,value);
}
}
// 删除节点
public void delete(T value) {
root = deleteRecursive(root, value);
}
// 递归实现删除节点
private TreeNode deleteRecursive(TreeNode root, T value) {
if (root == null) {
return null;
}
if (value.compareTo(root.value) < 0) {
root.left = deleteRecursive(root.left, value);
} else if (value.compareTo(root.value) > 0) {
root.right = deleteRecursive(root.right, value);
} else {
// 找到要删除的节点
if (root.left == null && root.right == null) {
// 叶节点,直接删除
return null;
} else if (root.left == null) {
// 只有右子树,用右子节点替代要删除的节点
return root.right;
} else if (root.right == null) {
// 只有左子树,用左子节点替代要删除的节点
return root.left;
} else {
// 左右子树都存在,找到右子树中最小的节点,替代要删除的节点
TreeNode minNode = findMin(root.right);
root.value = minNode.value;
root.right = deleteRecursive(root.right, minNode.value);
}
}
return root;
}
// 前序遍历
public void preOrderTraversal() {
preOrderTraversalRecursive(root);
}
private void preOrderTraversalRecursive(TreeNode node) {
if (node != null) {
System.out.print(node.value + " ");
preOrderTraversalRecursive(node.left);
preOrderTraversalRecursive(node.right);
}
}
// 中序遍历
public void inOrderTraversal() {
inOrderTraversalRecursive(root);
}
private void inOrderTraversalRecursive(TreeNode node) {
if (node != null) {
inOrderTraversalRecursive(node.left);
System.out.print(node.value + " ");
inOrderTraversalRecursive(node.right);
}
}
// 后序遍历
public void postOrderTraversal() {
postOrderTraversalRecursive(root);
}
private void postOrderTraversalRecursive(TreeNode node) {
if (node != null) {
postOrderTraversalRecursive(node.left);
postOrderTraversalRecursive(node.right);
System.out.print(node.value + " ");
}
}
/*
* 实现二叉树搜索树
*
* */
//因为是二叉搜索树所以要引入Comparable接口要不然引用类型无法比较
public class TreeNodeTest>{
private TreeNode root;//创建一个根节点
//创建节点类
private static class TreeNode{
T value;
TreeNode left;
TreeNode right;
//叶节点专属构造方法
public TreeNode(T value) {
this.value = value;
left = null;
right = null;
}
//默认构造方法
public TreeNode(T value, TreeNode left, TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
}
public TreeNodeTest() {
root = null;
}
//指定一个根节点创建树
public TreeNodeTest(TreeNode root) {
this.root = root;
}
//插入节点
public void insert(T value){
root = insertRecursive(root, value);
}
//递归实现插入节点
private TreeNode insertRecursive(TreeNode root, T value) {
if (root == null){
return new TreeNode<>(value);
}
if (value.compareTo(root.value) < 0){
//小于此节点往此节点后面子节点继续找
root.left = insertRecursive(root.left,value);
}else if (value.compareTo(root.value) > 0){
root.right = insertRecursive(root.right,value);
}
return root;
}
// 删除节点
public void delete(T value) {
root = deleteRecursive(root, value);
}
// 递归实现删除节点
private TreeNode deleteRecursive(TreeNode root, T value) {
if (root == null) {
return null;
}
if (value.compareTo(root.value) < 0) {
root.left = deleteRecursive(root.left, value);
} else if (value.compareTo(root.value) > 0) {
root.right = deleteRecursive(root.right, value);
} else {
// 找到要删除的节点
if (root.left == null && root.right == null) {
// 叶节点,直接删除
return null;
} else if (root.left == null) {
// 只有右子树,用右子节点替代要删除的节点
return root.right;
} else if (root.right == null) {
// 只有左子树,用左子节点替代要删除的节点
return root.left;
} else {
// 左右子树都存在,找到右子树中最小的节点,替代要删除的节点
TreeNode minNode = findMin(root.right);
root.value = minNode.value;
root.right = deleteRecursive(root.right, minNode.value);
}
}
return root;
}
// 查找最小值节点
private TreeNode findMin(TreeNode node) {
if (node.left == null) {
return node;
}
return findMin(node.left);
}
//查找节点
public boolean contains(T value) {
return containsRecursive(root, value);
}
//递归实现查找节点
private boolean containsRecursive(TreeNode root, T value) {
//递归的出口
if (root == null){
//意味着找到最后也没找到
return false;
}
if (value.compareTo(root.value) == 0){
return true;
}
if (value.compareTo(root.value) < 0){
return containsRecursive(root.left,value);
}else{
return containsRecursive(root.right,value);
}
}
// 前序遍历
public void preOrderTraversal() {
preOrderTraversalRecursive(root);
}
private void preOrderTraversalRecursive(TreeNode node) {
if (node != null) {
System.out.print(node.value + " ");
preOrderTraversalRecursive(node.left);
preOrderTraversalRecursive(node.right);
}
}
// 中序遍历
public void inOrderTraversal() {
inOrderTraversalRecursive(root);
}
private void inOrderTraversalRecursive(TreeNode node) {
if (node != null) {
inOrderTraversalRecursive(node.left);
System.out.print(node.value + " ");
inOrderTraversalRecursive(node.right);
}
}
// 后序遍历
public void postOrderTraversal() {
postOrderTraversalRecursive(root);
}
private void postOrderTraversalRecursive(TreeNode node) {
if (node != null) {
postOrderTraversalRecursive(node.left);
postOrderTraversalRecursive(node.right);
System.out.print(node.value + " ");
}
}
public static void main(String[] args) {
TreeNodeTest tree = new TreeNodeTest<>();
tree.insert(5);
tree.insert(3);
tree.insert(7);
tree.insert(1);
tree.insert(4);
tree.insert(6);
tree.insert(8);
System.out.println("前序遍历结果:");
tree.preOrderTraversal();
System.out.println("\n中序遍历结果:");
tree.inOrderTraversal();
System.out.println("\n后序遍历结果:");
tree.postOrderTraversal();
System.out.println("\n是否包含值为 4 的节点:" + tree.contains(4));
}
}