JAVA实现AVL树

定义:空树或者左子树和右子树高度差小于等于1且左右子树的子树也满足这个要求
在计算机科学中,AVL树是最早被发明的自平衡二叉查找树。在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是。增加和删除元素的操作则可能需要借由一次或多次树旋转,以实现树的重新平衡。 维基百科

public class AVLTreeDemo {
    public static void main(String[] args) {
        int[] arr = {10, 12, 8, 9, 7, 6};
        AVLTree avlTree = new AVLTree();
        for (int i = 0; i < arr.length; i++) {
            avlTree.add(new Node(arr[i]));
        }
        avlTree.infixOrder();
        System.out.println(avlTree.getRoot().height());
        System.out.println(avlTree.getRoot().leftHeight());
        System.out.println(avlTree.getRoot().rightHeight());
        System.out.println(avlTree.getRoot());

    }
}
//创建AVL树

class AVLTree {
    private Node root;

    public Node getRoot() {
        return root;
    }

    public Node search(int value) {
        if (root == null) return null;
        else return root.search(value);
    }

    public void add(Node node) {
        if (root == null) root = node;
        else root.add(node);
    }

    public void infixOrder() {
        if (root == null) System.out.println("二叉排序树为空,不能遍历");
        else root.infixOrder();
    }

}


class Node {
    int value;
    Node left;
    Node right;

    public Node(int value) {
        this.value = value;
    }

    //返回左子树高度
    public int leftHeight() {
        if (left == null) return 0;
        return left.height();
    }

    //返回右子树高度
    public int rightHeight() {
        if (right == null) return 0;
        return right.height();
    }

    //返回当前节点的高度(以该节点为根节点的树的高度)
    public int height() {
        return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1;
    }

    // 左旋转   右边高了,肯定有this.right
    private void leftRotate() {
        //创建新的节点,以当前根节点的值
        Node newNode = new Node(value);
        //把新的节点的左子树设置成当前节点左子树
        newNode.left = left;
        //把新的节点的右子树设置成右子树的左子树;
        newNode.right = right.left;
        //把当前节点的值替换成右子节点的值
        value = right.value;
        //把当前节点的右子树设置成右子树的右子树
        right = right = right;
        //把当前节点的左子树设置成新的节点
        left = newNode;
    }


    //右旋转  左边高了
    private void rightRotate() {
        Node newNode = new Node(value);
        newNode.right = right;
        newNode.left = left.right;
        value = left.value;
        this.left = left.left;
        this.right = newNode;
    }

    //查找要删除的节点
    public Node search(int value) {
        if (value == this.value) return this;
        else if (value < this.value) {
            if (this.left == null) return null;
            return this.left.search(value);
        } else {
            if (this.right == null) return null;
            return this.right.search(value);
        }
    }

    // 递归的形式添加节点,注意需要满足二叉排序数的要求
    public void add(Node node) {
        if (node == null) return;
        //判断传入的结点值,和当前子树的根节点的关系
        if (node.value < this.value) {
            if (this.left == null) this.left = node;
            else {
                this.left.add(node);
            }
        } else {
            if (this.right == null) this.right = node;
            else {
                this.right.add(node);
            }
        }
        //当添加完一个节点后  if(右子树的高度-左子树的高度>1  左旋)
        if (rightHeight() - leftHeight() > 1) {
            // 右子树的左子树高度大于右子树的右子节点树,  右旋,减小左边高度,增加右边高度
            if (right != null && right.leftHeight() > right.rightHeight()) {
                right.rightRotate();
            }
            leftRotate();
            return;   // 提高效率 这时候已经平衡
        }

        //左子树高度大于右子树高度 右旋
        if (leftHeight() - rightHeight() > 1) {
            //如果他的左子树的右节点高度大于其左节点高度
            if (left != null && left.rightHeight() > left.leftHeight()) {
                //先对当前节点的左节点  左旋转 减小右子树高度
                left.leftRotate();
            }
            rightRotate();
        }
    }

    public void infixOrder() {
        if (left != null) left.infixOrder();
        System.out.println(toString());
        if (right != null) right.infixOrder();
    }

    @Override
    public String toString() {

        return "Node: " + value + ";";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVL是一种自平衡的二叉搜索,它的升序遍历可以通过中序遍历来实现。下面是Java实现AVL升序遍历的示例代码: ```java // AVL节点定义 class Node { int key; int height; Node left; Node right; Node(int key) { this.key = key; this.height = 1; } } // AVL类定义 class AVLTree { Node root; // 获取节点的高度 int getHeight(Node node) { if (node == null) { return 0; } return node.height; } // 更新节点的高度 void updateHeight(Node node) { node.height = Math.max(getHeight(node.left), getHeight(node.right)) + 1; } // 获取节点的平衡因子 int getBalanceFactor(Node node) { if (node == null) { return 0; } return getHeight(node.left) - getHeight(node.right); } // 右旋操作 Node rotateRight(Node y) { Node x = y.left; Node T2 = x.right; x.right = y; y.left = T2; updateHeight(y); updateHeight(x); return x; } // 左旋操作 Node rotateLeft(Node x) { Node y = x.right; Node T2 = y.left; y.left = x; x.right = T2; updateHeight(x); updateHeight(y); return y; } // 插入节点 Node insertNode(Node node, int key) { if (node == null) { return new Node(key); } if (key < node.key) { node.left = insertNode(node.left, key); } else if (key > node.key) { node.right = insertNode(node.right, key); } else { return node; // 不允许插入重复的节点 } updateHeight(node); int balanceFactor = getBalanceFactor(node); // 左旋操作 if (balanceFactor > 1 && key < node.left.key) { return rotateRight(node); } // 右旋操作 if (balanceFactor < -1 && key > node.right.key) { return rotateLeft(node); } // 左右旋操作 if (balanceFactor > 1 && key > node.left.key) { node.left = rotateLeft(node.left); return rotateRight(node); } // 右左旋操作 if (balanceFactor < -1 && key < node.right.key) { node.right = rotateRight(node.right); return rotateLeft(node); } return node; } // 中序遍历 void inorderTraversal(Node node) { if (node != null) { inorderTraversal(node.left); System.out.print(node.key + " "); inorderTraversal(node.right); } } } // 测试代码 public class Main { public static void main(String[] args) { AVLTree tree = new AVLTree(); tree.root = tree.insertNode(tree.root, 10); tree.root = tree.insertNode(tree.root, 20); tree.root = tree.insertNode(tree.root, 30); tree.root = tree.insertNode(tree.root, 40); tree.root = tree.insertNode(tree.root, 50); tree.root = tree.insertNode(tree.root, 25); System.out.println("AVL的升序遍历结果:"); tree.inorderTraversal(tree.root); } } ``` 运行以上代码,输出结果为:10 20 25 30 40 50,即AVL的升序遍历结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值