zoukankan      html  css  js  c++  java
  • 平衡二叉树--java

    package com.test.tree;
    
    /**
     * 带有平衡条件的二叉查找树
     * */
    public class AVLBinarySearchTree<T extends Comparable<? super T>> {
        
        /*内部类,定义二叉树中的节点结构*/
        private static class TreeNode<T>{
            private T data; //节点的值
            private TreeNode<T> lt; //节点左子树
            private TreeNode<T> rt; //节点右子树
            private int height; //用来记录节点的高度,进行单旋转或双旋转
            
            public TreeNode(T data) {
                this(data, null, null);
            }
            public TreeNode(T data, TreeNode<T> lt, TreeNode<T> rt) {
                this.data = data;
                this.lt = lt;
                this.rt = rt;
                this.height = 0;
            }
            public T getData() {
                return data;
            }
            public void setData(T data) {
                this.data = data;
            }
            public TreeNode<T> getLt() {
                return lt;
            }
            public void setLt(TreeNode<T> lt) {
                this.lt = lt;
            }
            public TreeNode<T> getRt() {
                return rt;
            }
            public void setRt(TreeNode<T> rt) {
                this.rt = rt;
            }
            public int getHeight() {
                return height;
            }
            public void setHeight(int height) {
                this.height = height;
            }
        }
        
        /**
         * 计算节点的高度
         * @param t 输入子树
         * @return 返回树的高度
         */
        public int height(TreeNode<T> t){
            return t==null ? -1 : t.height;
        }
        
        /**
         * 给树中添加节点
         * @param data 要插入的节点值
         * @param t 要插入的子树
         * @return 插入后形成的新的树
         */
        public TreeNode<T> insert(T data, TreeNode<T> t){
            if(t == null){
                //树为空
                return new TreeNode<T>(data, null ,null);
            }
            int compareReslt = compare(data, t.data);
            if(compareReslt < 0){
                //插入的数小于节点数,放入左子树中
                t.lt = insert(data, t.lt) ; //递归插入左子树
                
                //插入后检查当前节点的左右子树是否平衡
                if(height(t.lt)-height(t.rt) == 2){
                    if(compare(data, t.lt.data) < 0){
                        t = rotateWithLeftChild(t); //单旋转
                    }else if(compare(data, t.lt.data) > 0){
                        t = doubleWithLeftChild(t); //双旋转
                    }
                }
            }else if(compareReslt > 0){
                //插入的数大于节点数,放入右子树中
                t.rt = insert(data, t.rt) ; //递归插入左子树
                
                //插入后检查当前节点的左右子树是否平衡
                if(height(t.rt)-height(t.lt) == 2){
                    if(compare(data, t.rt.data) > 0){
                        t = rotateWithRightChild(t); //单旋转
                    }else if(compare(data, t.rt.data) > 0){
                        t = doubleWithRightChild(t); //双旋转
                    }
                }
            }
            t.height = Math.max(height(t.lt), height(t.rt)) + 1;
            return t;
        }
        private TreeNode<T> rotateWithRightChild(TreeNode<T> k2) {
            // TODO Auto-generated method stub
            TreeNode<T> k1 = k2.rt; 
            k2.rt = k1.lt; //左子树的右节点介于左子树根节点和根节点之间,赋值给根节点的左子树
            k1.lt = k2; //将根节点赋值给左节点的右节点
            k2.height = Math.max(height(k2.lt), height(k2.rt)) + 1;
            k1.height = Math.max(height(k1.rt), k2.height) + 1;
            return k1;
        }
    
        private TreeNode<T> doubleWithRightChild(TreeNode<T> k3) {
            // TODO Auto-generated method stub
            k3.rt = rotateWithLeftChild(k3.rt);
            return rotateWithRightChild(k3);
        }
    
        /**
         * 单旋转
         * @param t
         * @return
         */
        private TreeNode<T> rotateWithLeftChild(TreeNode<T> k2) {
            // TODO Auto-generated method stub
            TreeNode<T> k1 = k2.lt; //左子树的根节点赋给K1
            k2.lt = k1.rt; //左子树的右节点介于左子树根节点和根节点之间,赋值给根节点的左子树
            k1.rt = k2; //将根节点赋值给左节点的右节点
            k2.height = Math.max(height(k2.lt), height(k2.rt)) + 1;
            k1.height = Math.max(height(k1.lt), k2.height) + 1;
            return k1;
        }
        /**
         * 双旋转
         * @param t
         * @return
         */
        private TreeNode<T> doubleWithLeftChild(TreeNode<T> k3) {
            // TODO Auto-generated method stub
            k3.lt = rotateWithRightChild(k3.lt);
            return rotateWithLeftChild(k3);
        }
    
        /**
         * 比较两个值是否相等
         * @param data1
         * @param data2
         * @return
         */
        public int compare(T data1, T data2){
            return data1.compareTo(data2);
        }
        
        /*中序遍历*/
        public void printTree(TreeNode<T> t){
            if(t != null){
                printTree(t.lt);
                System.out.print(t.data+"、");
                printTree(t.rt);
            }
        }
        
        public static void main(String[] args) {
            AVLBinarySearchTree<Integer> aVLBinarySearchTree = new AVLBinarySearchTree<Integer>();
            TreeNode<Integer> node = new TreeNode<Integer>(8);
            node = aVLBinarySearchTree.insert(6, node);
            node = aVLBinarySearchTree.insert(16, node);
            node = aVLBinarySearchTree.insert(13, node);
            node = aVLBinarySearchTree.insert(19, node);
            node = aVLBinarySearchTree.insert(7, node);
            node = aVLBinarySearchTree.insert(21, node);
            node = aVLBinarySearchTree.insert(23, node);
            aVLBinarySearchTree.printTree(node.lt);
            aVLBinarySearchTree.printTree(node.rt);
        }
    }
  • 相关阅读:
    线程池
    多线程随笔
    注解随笔
    反射机制
    iO流
    FastDFS+docker建立分布式文件系统
    Java之Exception
    Java之String
    手写SpringMvc
    spring中一些常用注解的含义
  • 原文地址:https://www.cnblogs.com/studyDetail/p/7153782.html
Copyright © 2011-2022 走看看