[java]二叉树构建、遍历、深度、平衡性

来源:互联网 发布:安广网络客服电话 编辑:程序博客网 时间:2024/06/07 02:50
package tree;/** * 2017-3-15 * 剑指offer-P55 * @author victorlee * */public class ConstructTree{    public Tree construct(int[] pre,int[] in){        if(pre.length ==0 || in.length == 0)            return null;        Tree head = buildTree(pre,0,pre.length-1,in,0,in.length-1);        return head;    }    /**     * 通过   前序遍历和中序遍历重建二叉树     * @param preOrder     * @param begin1     * @param end1     * @param inOrder     * @param begin2     * @param end2     * @return     */    public Tree buildTree(int[] preOrder, int begin1, int end1, int[] inOrder, int begin2, int end2) {    // TODO Auto-generated method stub        if(begin1>end1||begin2>end2){            return null;        }        int rootData = preOrder[begin1];//前序的第一个数字总是树的根节点包含的数值        Tree head = new Tree(rootData);//初始化树的根节点        int divider = findIndexInArray(inOrder,rootData,begin2,end2);//找到根节点的值在中序遍历数组中的位置(索引下标)        int offSet = divider -begin2 -1;//在中序遍历数组中,左子树最后一个结点的下标        Tree left = buildTree(preOrder,begin1+1,begin1+1+offSet,inOrder,begin2,begin2+offSet);        Tree right = buildTree(preOrder,begin1+offSet+2,end1,inOrder,divider+1,end2);        head.left_child = left;        head.right_child = right;           return head;    }    private int findIndexInArray(int[] a, int x, int begin, int end) {        // TODO Auto-generated method stub        for(int i = begin;i<=end;i++){            if(a[i]==x)                return i;        }        return -1;    }    public void inOrder(Tree n){        if(n!=null){            inOrder(n.left_child);            System.out.print(n.val+" ");            inOrder(n.right_child);        }    }    public void preOrder(Tree n){        if(n!=null){            System.out.print(n.val+" ");            preOrder(n.left_child);            preOrder(n.right_child);        }    }    public void behindOrder(Tree n){        if(n!= null){            behindOrder(n.left_child);            behindOrder(n.right_child);            System.out.print(n.val+" ");        }    }    /**     * 递归求得树的深度     * @param head     * @return     */    public int treeDepth(Tree head){        if(head == null)            return 0;        int nLeft = treeDepth(head.left_child);        int nRight = treeDepth(head.right_child);        return (nLeft > nRight)?(nLeft +1):(nRight +1);    }    /**     * 2017-3-17     * 使用递归的方法判断一棵树是不是平衡二叉树     * 缺点:一个结点会被多次遍历。     * @param args     */    public boolean isBanlanced(Tree root){        if(root == null){            return true;        }        int left = treeDepth(root.left_child);        int right = treeDepth(root.right_child);        int diff = left -right;        if(diff>1||diff<-1){            return false;        }        return isBanlanced(root.left_child)&&isBanlanced(root.right_child);    }    /**     * 2017-3-17     * 一个结点只需要遍历一次就可以求得该二叉树是不是平衡二叉树     * @param root     * @param depth     * @return     */    public boolean isBalanced(Tree root,int depth){        if(root == null){            depth = 0;            return true;        }        int left=0,right=0;        if(isBalanced(root.left_child,left)&&isBalanced(root.right_child,right)){            int diff = left-right;            if(diff<=1 &&diff>=-1){                depth = 1+(left>right?left:right);                return true;            }        }        return false;    }    //优化后的方法:一方面可以在计算左右子树的高度时,判断是否为平衡二叉树。    public boolean isBalanced3(Tree root){        return getHeight(root)!=-1;    }    private int getHeight(Tree root){        if(root==null) return 0;        int nLeft=getHeight(root.left_child);        if(nLeft==-1) return -1;        int nRight=getHeight(root.right_child);        if(nRight==-1) return -1;        if(nLeft-nRight<-1||nLeft-nRight>1)            return -1;        return 1+(nLeft>nRight?nLeft:nRight);    }    public static void main(String[] args){        ConstructTree build =new ConstructTree();        int[] preOrder = {1,2,4,7,3,5,6,8};        int[] inOrder = {4,7,2,1,5,3,8,6};        Tree root = build.construct(preOrder, inOrder);        System.out.print("前序遍历为:");        build.preOrder(root);//检验构建的二叉树前序遍历是否正确        System.out.println();        System.out.print("中序遍历为:");        build.inOrder(root);//检验构建的二叉树中序遍历是否正确        System.out.println();        System.out.print("后序遍历为:");        build.behindOrder(root);        System.out.print("树的深度为:");        int treeDepth = build.treeDepth(root);        System.out.println(treeDepth);    }   }