二叉搜索树是一种特殊的二叉树,它的每一个节点都满足以下条件:
通过这种特殊的结构,二叉搜索树能够实现快速的插入、查找和删除操作。在二叉搜索树中,插入一个新节点的时间复杂度为 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
extends Comparable>{ -
- 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
extends Comparable>{ -
- 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));
- }
- }
-
-
-
-