平衡二叉树的实现 java

平衡二叉树的实现:
程序输出结果为:

前序遍历结果:
8   5   2   7   6   9   69   
中序遍历结果
2    5    6    7    8    9    69
 
两种遍历结果可以唯一确定一颗二叉树,从而得出二叉树如下图所示:为一颗平衡二叉树。 
代码如下所示:

package AlgorithmTest;

/**
 * Created by dell on 2016/12/14.
 */
import java.util.ArrayList;
import java.util.Collections;

/**
 *
 * 平衡二叉树编写的有两个突破口,
 * 1、一个假设这颗二叉树已经是一个平衡二叉树,加入一个节点之后,不平衡了需要调整的也只有最末的那颗不平衡的树
 * 2、插入一个节点时如果这个节点,只有这个节点经过的节点有影响平衡因子,
 * 如果这个节点应该插入某个节点的左子树则,平衡因子+1,假设平衡因为=左子树高度-右子数高度
 * 3、最末的各个不平衡书的所有节点,要记录,调整完之后,这些节点的平衡因子要减一;
 *  @author  liyiwen1
 *  @date  2016/12/11
 */
public class AVLTree  {
    public static void main(String[] args) {
        AVLTree avlTree =  new AVLTree();
        Integer[] integers =  new Integer[]{ 8, 9, 2, 7, 5, 2, 69, 7, 2, 6};
        for (Integer i : integers){
            avlTree.insert(i);
        }
        System. out.println( "前序遍历结果:");
        avlTree.preOrder(avlTree.getRoot());
        System. out.println();
        System. out.println( "中序遍历结果");
        avlTree.midOrder(avlTree.getRoot());
    }
    private static class AVLTreeNode  implements Comparable<AVLTreeNode>{
        private Comparable  value;
        private int  balanceUnit 0;
        private AVLTreeNode  left;
        private AVLTreeNode  rigtht;

        @Override
        public int compareTo(AVLTreeNode a){
            return  value.compareTo(a.getValue());
        }
        public Comparable getValue() {
            return  value;
        }

        public void setValue(Comparable value) {
            this. value = value;
        }

        public int getBalanceUnit() {
            return  balanceUnit;
        }

        public void setBalanceUnit( int balanceUnit) {
            this. balanceUnit = balanceUnit;
        }

        public AVLTreeNode getLeft() {
            return  left;
        }

        public void setLeft(AVLTreeNode left) {
            this. left = left;
        }

        public AVLTreeNode getRigtht() {
            return  rigtht;
        }

        public void setRigtht(AVLTreeNode rigtht) {
            this. rigtht = rigtht;
        }

        public AVLTreeNode(Comparable value) {
            this. value = value;
        }
    }

    private AVLTreeNode  root;



    public AVLTree() {
    }

    private void insert(Comparable value){
        if ( root ==  null){
            root new AVLTreeNode(value);
            root.setBalanceUnit( 0);
            root.setLeft( null);
            root.setRigtht( null);
            return;
        }

        if (find(value)){
            return; //如果相等则直接返回,不存储value相同的节点
        }
        AVLTreeNode needRotationTreeRoot =  null;
        AVLTreeNode treeNode =  this. root;
        ArrayList<AVLTreeNode> avlTreeNodes =  new ArrayList<AVLTreeNode>();
        while ( true){
            avlTreeNodes.add(treeNode); //所经过的父节点都保存起来
            if (value.compareTo(treeNode.getValue()) >  0){
                treeNode. balanceUnit--; //如果插入值大于父节点则平衡因子减一
                if (treeNode. balanceUnit >=  || treeNode. balanceUnit <= - ){
                    needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
                }
                if (treeNode.getRigtht() ==  null){
                    treeNode.setRigtht( new AVLTreeNode(value));
                    break;
                } else{
                    treeNode = treeNode.getRigtht(); //继续往右边走
                }
             } else if (value.compareTo(treeNode.getValue()) <  0){
                treeNode. balanceUnit++; //如果插入的值小于父节点的值,则父节点的平衡因子加一
                if (treeNode. balanceUnit >=  || treeNode. balanceUnit <= - 2){
                    needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
                }
                if (treeNode.getLeft() ==  null){
                    treeNode.setLeft( new AVLTreeNode(value));
                    break;
                } else{
                    treeNode = treeNode.getLeft();
                }
            }
        }
        if (needRotationTreeRoot ==  null){
            return ; //没有半个失去平衡的节点,则返回
        } else{
            for ( int i =  0; i < avlTreeNodes.size() -  ; i++){ //后两个父节点由于处于调节的范畴,不进行平衡因子绝对值的调整
                if (avlTreeNodes.get(i). balanceUnit 0){
                    avlTreeNodes.get(i). balanceUnit--;
                } else if (avlTreeNodes.get(i). balanceUnit 0){
                    avlTreeNodes.get(i). balanceUnit++;
                }
            }
            if (avlTreeNodes.size() >=  3){
                rotation(needRotationTreeRoot, avlTreeNodes.get(avlTreeNodes.size() -  3)); //父节点只有3个已上
            } else{
                rotation(needRotationTreeRoot,  null); //父节点只有两个
            }
        }
    }

    public boolean find(Comparable value){
        AVLTreeNode node = getRoot();
        while (node !=  null){
            if (node.getValue().compareTo(value) ==  0){
                return true;
            } else if (node.getValue().compareTo(value) >  0){
                node = node.getLeft();
            } else{
                node = node.getRigtht();
            }
        }
        return false;
    }

    public void preOrder(AVLTreeNode node){
        if (node !=  null){
            System. out.print(node.getValue() +  "   ");
            preOrder(node.getLeft());
            preOrder(node.getRigtht());
        }
    }

    public void midOrder(AVLTreeNode node){
        if (node !=  null){
            midOrder(node.getLeft());
            System. out.print(node.getValue() +  "    ");
            midOrder(node.getRigtht());
        }
    }

    //needRotationTreeRootFather表示最末端的不平衡二叉树的根节点的父节点,这里有个特例即needRotationTreeRootFather为null
    private void rotation(AVLTreeNode needRotationTreeRoot, AVLTreeNode needRotationTreeRootFather){
        ArrayList<AVLTreeNode> nodes =  new ArrayList<AVLTreeNode>();
        transase(needRotationTreeRoot, nodes);
        Collections. sort(nodes);
        for (AVLTreeNode node: nodes){
            node.setLeft( null);
            node.setRigtht( null);
            node.setBalanceUnit( 0);
        }
        nodes.get( 1).setLeft(nodes.get( 0));
        nodes.get( 1).setRigtht(nodes.get( 2));
        if (needRotationTreeRootFather ==  null){
            this. root = nodes.get( 1);
            return ; //处理needRotationTreeRootFather为null的情况
        }
        if (needRotationTreeRootFather.getLeft() == needRotationTreeRoot){
            needRotationTreeRootFather.setLeft(nodes.get( 1));
        } else if (needRotationTreeRootFather.getRigtht() == needRotationTreeRoot){
            needRotationTreeRootFather.setRigtht(nodes.get( 1));
        } else{
            throw new RuntimeException();
        }
    }

    private void transase(AVLTreeNode root, ArrayList<AVLTreeNode> nodes){
        if (root !=  null){
            nodes.add(root);
            transase(root.getLeft(), nodes);
            transase(root.getRigtht(), nodes);
        }
    }

    private AVLTreeNode getRoot() {
        return  root;
    }

    private void setRoot(AVLTreeNode root) {
        this. root = root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值