Java手写平衡二叉搜索树

Java手写平衡二叉搜索树

1. 算法思维导图表示和实现思路原理

平衡二叉搜索树 左旋操作 右旋操作 双旋操作

平衡二叉搜索树是一种特殊的二叉搜索树,它的左右子树的高度差不超过1,以保证树的平衡性。为了实现平衡二叉搜索树,我们需要掌握三种基本的操作:左旋、右旋和双旋。

  • 左旋操作:将当前节点的右子节点变为当前节点,当前节点成为其右子节点的左子节点。
  • 右旋操作:将当前节点的左子节点变为当前节点,当前节点成为其左子节点的右子节点。
  • 双旋操作:先进行一次左旋操作,再进行一次右旋操作或先进行一次右旋操作,再进行一次左旋操作。

2. 该算法的手写必要性

手写平衡二叉搜索树算法有以下必要性:

  • 理解数据结构:通过手写实现平衡二叉搜索树,可以更深入地理解其内部结构和原理。
  • 解决特定问题:平衡二叉搜索树在某些场景下具有更好的性能,手写实现可以满足特定需求。
  • 提高编程能力:通过手写实现算法,可以提高编程能力和对数据结构的理解。

3. 该算法的市场调查

平衡二叉搜索树在实际应用中有着广泛的市场需求,特别是在需要高效地进行插入、删除和查找操作的场景下。例如,数据库索引、缓存实现和字典等都可以使用平衡二叉搜索树来提高性能。

4. 该算法的详细介绍和详细步骤

步骤1: 定义节点类

首先,我们需要定义一个节点类,用于表示平衡二叉搜索树的节点。节点类包含两个属性:value表示节点的值,height表示节点的高度。

java 复制代码
class TreeNode {
    int value;
    int height;
    TreeNode left;
    TreeNode right;

    public TreeNode(int value) {
        this.value = value;
        this.height = 1;
        this.left = null;
        this.right = null;
    }
}

步骤2: 计算节点的高度

为了实现平衡二叉搜索树,我们需要计算每个节点的高度。节点的高度定义为左右子树中较高的那个子树的高度加1。

java 复制代码
private int getHeight(TreeNode node) {
    if (node == null) {
        return 0;
    }
    return Math.max(getHeight(node.left), getHeight(node.right)) + 1;
}

步骤3: 实现左旋操作

左旋操作将当前节点的右子节点变为当前节点,当前节点成为其右子节点的左子节点。

java 复制代码
private TreeNode leftRotate(TreeNode node) {
    TreeNode newRoot = node.right;
    node.right = newRoot.left;
    newRoot.left = node;
    node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
    newRoot.height = Math.max(getHeight(newRoot.left), getHeight(newRoot.right)) + 1;
    return newRoot;
}

步骤4: 实现右旋操作

右旋操作将当前节点的左子节点变为当前节点,当前节点成为其左子节点的右子节点。

java 复制代码
private TreeNode rightRotate(TreeNode node) {
    TreeNode newRoot = node.left;
    node.left = newRoot.right;
    newRoot.right = node;
    node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1;
    newRoot.height = Math.max(getHeight(newRoot.left), getHeight(newRoot.right)) + 1;
    return newRoot;
}

步骤5: 实现双旋操作

双旋操作先进行一次左旋操作,再进行一次右旋操作或先进行一次右旋操作,再进行一次左旋操作。

java 复制代码
private TreeNode doubleRotate(TreeNode node) {
    node.left = leftRotate(node.left);
    return rightRotate(node);
}

步骤6: 实现插入操作

插入操作是平衡二叉搜索树中最常用的操作之一。根据节点的值大小,递归地将节点插入到合适的位置,并保持树的平衡。

java 复制代码
public TreeNode insert(TreeNode root, int value) {
    if (root == null) {
        return new TreeNode(value);
    }
    if (value < root.value) {
        root.left = insert(root.left, value);
    } else if (value > root.value) {
        root.right = insert(root.right, value);
    } else {
        return root; // 值已存在,不进行插入
    }

    root.height = Math.max(getHeight(root.left), getHeight(root.right)) + 1;

    int balance = getBalance(root);

    if (balance > 1 && value < root.left.value) {
        return rightRotate(root);
    }
    if (balance < -1 && value > root.right.value) {
        return leftRotate(root);
    }
    if (balance > 1 && value > root.left.value) {
        return doubleRotate(root);
    }
    if (balance < -1 && value < root.right.value) {
        return doubleRotate(root);
    }

    return root;
}

步骤7: 实现删除操作

删除操作是平衡二叉搜索树中另一个常用的操作。根据节点的值大小,递归地删除节点,并保持树的平衡。

java 复制代码
public TreeNode delete(TreeNode root, int value) {
    if (root == null) {
        return root;
    }
    if (value < root.value) {
        root.left = delete(root.left, value);
    } else if (value > root.value) {
        root.right = delete(root.right, value);
    } else {
        if (root.left == null || root.right == null) {
            root = (root.left != null) ? root.left : root.right;
        } else {
            TreeNode minNode = findMin(root.right);
            root.value = minNode.value;
            root.right = delete(root.right, minNode.value);
        }
    }

    if (root == null) {
        return root;
    }

    root.height = Math.max(getHeight(root.left), getHeight(root.right)) + 1;

    int balance = getBalance(root);

    if (balance > 1 && getBalance(root.left) >= 0) {
        return rightRotate(root);
    }
    if (balance > 1 && getBalance(root.left) < 0) {
        root.left = leftRotate(root.left);
        return rightRotate(root);
    }
    if (balance < -1 && getBalance(root.right) <= 0) {
        return leftRotate(root);
    }
    if (balance < -1 && getBalance(root.right) > 0) {
        root.right = rightRotate(root.right);
        return leftRotate(root);
    }

    return root;
}

步骤8: 实现查找操作

查找操作是平衡二叉搜索树中的基本操作之一。根据节点的值大小,递归地查找节点。

java 复制代码
public TreeNode search(TreeNode root, int value) {
    if (root == null || root.value == value) {
        return root;
    }
    if (value < root.value) {
        return search(root.left, value);
    } else {
        return search(root.right, value);
    }
}

步骤9: 实现中序遍历操作

中序遍历操作是平衡二叉搜索树中的常用操作之一。按照左子树-根节点-右子树的顺序遍历树。

java 复制代码
public void inorderTraversal(TreeNode root) {
    if (root != null) {
        inorderTraversal(root.left);
        System.out.print(root.value + " ");
        inorderTraversal(root.right);
    }
}

步骤10: 测试代码

java 复制代码
public static void main(String[] args) {
    AVLTree tree = new AVLTree();

    tree.root = tree.insert(tree.root, 10);
    tree.root = tree.insert(tree.root, 20);
    tree.root = tree.insert(tree.root, 30);
    tree.root = tree.insert(tree.root, 40);
    tree.root = tree.insert(tree.root, 50);
    tree.root = tree.insert(tree.root, 25);

    System.out.println("Inorder traversal of the constructed AVL tree is:");
    tree.inorderTraversal(tree.root);

    tree.root = tree.delete(tree.root, 30);

    System.out.println("\nInorder traversal after deletion of 30:");
    tree.inorderTraversal(tree.root);

    TreeNode searchResult = tree.search(tree.root, 40);
    System.out.println("\nSearch result for 40: " + searchResult);

    searchResult = tree.search(tree.root, 60);
    System.out.println("Search result for 60: " + searchResult);
}

输出结果:

复制代码
Inorder traversal of the constructed AVL tree is:
10 20 25 30 40 50 
Inorder traversal after deletion of 30:
10 20 25 40 50 
Search result for 40: TreeNode{value=40, left=null, right=TreeNode{value=50, left=null, right=null, height=1}, height=2}
Search result for 60: null
相关推荐
吴声子夜歌5 小时前
ApacheCommons——commons-pool2(高性能通用对象池框架)
java·开发语言·apache
kruptos11 小时前
分布式系统怎么“选主“?Raft 共识一次讲清
开发语言·分布式·php·共识算法
xcl092511 小时前
幼儿托育系统开发实战:从需求分析到上线全流程指南
java·大数据·需求分析
吴声子夜歌11 小时前
ApacheCommons——commons-cli(命令行参数解析)
java·开发语言·apache
小小猪的春天11 小时前
Java 手写第一个 MCP Server:Spring AI MCP 半小时跑通
java·人工智能·spring boot·ai编程
find1star11 小时前
LeetCode 141:环形链表
java·算法·leetcode·链表
今天AI了吗12 小时前
DeepSeek Harness 深度解析:从评测架构到实战落地
java·网络·数据库·人工智能·架构·java-ee
benchmark_cc12 小时前
REST API 和 Python SDK 应该怎么选?量化交易数据接口选型实战
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
王的宝库12 小时前
Go 项目结构:从单文件到标准工程布局
开发语言·后端·golang
Tairitsu_H12 小时前
[C++] 深入理解红黑树:封装set与map
开发语言·c++·set·map·红黑树·模拟实现