您的位置:首页 > 编程语言 > Java开发

平衡二叉树的实现 java

2016-12-15 00:17 405 查看
平衡二叉树的实现:
程序输出结果为:

前序遍历结果:
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 >= 2 || treeNode.balanceUnit <= -2 ){

                    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 >= 2 || 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() - 2 ; 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;

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息