平衡二叉树的实现

package tree.myavl;

import tree.Node;

/**
 * Created by lijie35 on 2020-01-15 6:37 PM .
 */
public class BalanceTree {

    private static final int LEFT = 0 ;
    private static final int RIGHT = 1 ;
    Node root;

    public void put(int val) {
        this.root = putVal(root, val);
    }

    /**
     * 插入数据
     */
    private Node putVal(Node node, int val) {

        if (node == null) {
            node = new Node(val);
        }

        //和当前节点比较,大于当前值的,往左节点走
        //left
        if (val < node.val) {
            node.leftChild = putVal(node.leftChild, val);
            //判断是否失衡
            if(caclTreeHeight(node,LEFT) ==2) {
                //判断节点时左右,还是左左
                if (node.leftChild.val > val) { //往左走>>右旋
                    node = rightRotation(node);
                } else {
                    node = leftRightRotation(node);
                }
            }

        }

        //往右节点走
        //right
        if (val > node.val) {
            node.rightChild = putVal(node.rightChild, val);
            if(caclTreeHeight(node,RIGHT) == 2) {
                //判断节点时右左,还是右右
                if (node.rightChild.val > val) { //往右走>>左旋
                    node = leftRotation(node);
                } else {
                    node = rightLeftRotation(node);
                }
            }

        }


        return node;
    }


    /**
     * 左旋 >>针对的是右右的情况
     * <p>
     *     5
     *    / \
     *   4   7
     *      / \
     *     6   8
     *          \
     *           9
     * **************************************
     *       7
     *      / \
     *     5   8
     *    / \   \
     *   4   6   9
     */
    public Node leftRotation(Node node) {
        //当前节点的有节点
        Node rightNode = node.rightChild;
        node.rightChild = rightNode.leftChild;
        rightNode.leftChild = node;
        return rightNode;
    }

    /**
     * 右旋 >>针对的是左左的情况
     * <p>
     *        7
     *       / \
     *      5   9
     *     / \
     *    3   6
     *   /
     *  1
     * **************************************
     *        5
     *       / \
     *      3   7
     *     /   / \
     *    1    6  9
     */
    public Node rightRotation(Node node) {
        //当前节点的有节点
        Node leftNode = node.leftChild;
        node.leftChild = leftNode.rightChild;
        leftNode.rightChild = node;
        return leftNode;
    }

    /**
     * 左右旋 >>针对的是左右的情况
     *      8
     *     / \
     *    5   9
     *   / \
     *  3   6
     *       \
     *        7
     * **************************************
     *        8
     *       / \
     *      6   9
     *     / \
     *    5   7
     *   /
     *  3
     * **************************************
     *         6
     *        / \
     *       5   8
     *      /   / \
     *     3   7   9
     */
    public Node leftRightRotation(Node node) {
        //先左旋,不平衡点的左节点赋值
        node.leftChild = leftRotation(node.leftChild);
        return rightRotation(node);
    }

    /**
     * 右左旋 >>针对的是右左的情况
     *       3
     *      / \
     *     1   9
     *        / \
     *       5   11
     *      /
     *     4
     * **************************************
     *       3
     *      / \
     *     1   5
     *        / \
     *       4   9
     *            \
     *            11
     * **************************************
     *        5
     *       / \
     *      3   8
     *     / \   \
     *    1   4   11
     * @param node 失衡点
     */
    public Node rightLeftRotation(Node node) {
        node.rightChild = rightRotation(node.rightChild);
        return leftRotation(node);
    }


    //计算当前节点高度
    public int getChildDepth(Node node) {
        if (node == null) {
            return 0;
        }
        return 1 + Math.max(getChildDepth(node.leftChild), getChildDepth(node.rightChild));
    }

    //计算左右子树高度差
    public int caclTreeHeight(Node node, int leftright){
        if(node == null){
            return 0;
        }

        if(leftright == LEFT){ //左边高,所以左-右
            return getChildDepth(node.leftChild) - getChildDepth(node.rightChild);
        }else if(leftright == RIGHT){ //右边高, 右减左
            return getChildDepth(node.rightChild) - getChildDepth(node.leftChild);
        }

        return 0;
    }

    //中序遍历
    public void  midTraverse(Node node){
        if(node!=null) {
            midTraverse(node.leftChild);
            System.out.println(node.val);
            midTraverse(node.rightChild);
        }
    }

    public static void main(String[] args) {
        BalanceTree tree=new BalanceTree();
        tree.put(9);
        tree.put(6);
        tree.put(10);
        tree.put(5);
        tree.put(7);
        tree.put(8);

        System.out.println("#####################");
        tree. midTraverse(tree.root);
    }


}

node

public class Node {
    

    public Node leftChild;

    public Node rightChild;

    public Integer val;

    public Node(Integer val) {
        this.val = val;
    }

  
    public Node(Node left, Node right, Integer val) {
       
        this.leftChild = left;
        this.rightChild = right;
        this.val = val;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "val='" + val + '\'' +
                '}';
    }
}

发布了30 篇原创文章 · 获赞 0 · 访问量 1007

猜你喜欢

转载自blog.csdn.net/l4oli/article/details/104003658