(5)二叉树

二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”,左子树和右子树同时也是二叉树。
二叉树若直接定义可能会造成畸形,对树畸形的改进一般有两种方法,
- 方法一:平衡二叉树。
- 方法二:红黑树。
对平衡二叉树的定义:左右子树的高度相差不超过1。
调整方法:http://blog.csdn.net/a454042522/article/details/8591421

下面通过平衡二叉树方法写一棵树:

//递归定义法
//递归定义法中将每个节点看成一颗二叉树
class BiTree{
    private int data;//数据
    private BiTree left;//左子树
    private BiTree right;//又子树
    private int balance = 0;//平衡因子,避免树畸形

    public BiTree(int data){
        this.data = data;
    }

    public void calcu_balance(){//计算平衡因子
        int leftH = left==null ? 0 : left.getHeight();
        int rightH = right==null ? 0 : right.getHeight();
        balance = leftH-rightH;
    }

    public BiTree add(BiTree biTrees){//添加二叉树
        BiTree root = this;
        if(biTrees.data < data){//如果要添加的数据小于当前节点数据,就添加到左子树
            if(left == null){//如果左子树为空,直接添加
                left = biTrees;
            }else{//否者递归调用。返回新节点
                left = left.add(biTrees);
            }
        }else{//如果要添加的数据大于当前节点数据,就添加到右子树
            if(right == null){
                right = biTrees;
            }else{
                right = right.add(biTrees);
            }
        }

        calcu_balance();//添加完成之后重新计算平衡

        if(balance>2){//左边太重
            if(left.getBalance()>0){
                root = adjustLL();
            }
            else{
                root = adjustLR();
            }
        }

        if(balance<-2){
            if(right.getBalance()<0){
                root = adjustRR();
            }else{
                root = adjustRL();
            }
        }

        calcu_balance();
        return root;
    }

    //返回树显示的高度
    public int getHeight(){
        int h = 2;
        int hleft = left==null? 0 : left.getHeight();
        int rleft = right==null? 0 : right.getHeight();
        return h + Math.max(hleft, rleft);
    }

    //返回树的宽度
    public int getWidth(){
        int w = (""+data).length();
        if(left!=null){
            w += left.getWidth();
        }
        if(right!=null){
            w += right.getWidth();
        }
        return w;
    }

    public int getBalance(){
        return balance;
    }

    //调整LL型,进行右旋
    private BiTree adjustLL(){
        BiTree root = left;//将左子树纪录为根
        left = root.right;//将原来根的右边挂在新根的左边
        root.right = this;//根的右边等于自身
        return root;
    }

    private BiTree adjustRR(){
        BiTree root = right;
        right = root.left;
        root.left = this;
        return root;
    }

    private BiTree adjustLR(){//调整LR型,先左旋再右旋
        left = left.adjustRR();
        return adjustLL();
    }

    private BiTree adjustRL(){
        right = right.adjustLL();
        return adjustRR();
    }

    //将二叉树结构打印出来
    public void show(){
        char[][] buf = new char[getHeight()][getWidth()];
        printBuf(buf,0,0);
        showBuf(buf);
    }

    private void showBuf(char[][] buf) {
        for(int i=0; i<buf.length; i++){
            for(int j=0; j<buf[i].length; j++){
                System.out.print(buf[i][j]==0?' ':buf[i][j]);

            }System.out.println();
        }
    }
    private void printBuf(char[][] buf, int i, int j) {
        String sv = "" + data;
        int p1 = left==null ? i : left.getRootPos(i);
        int p2 = getRootPos(i);
        int p3 = right==null ? p2 : right.getRootPos(p2+sv.length());

        buf[j][p2] = '|';
        for(int k = p1; k<=p3; k++){
            buf[j+1][k] = '-';
        }
        for(int k=0; k<sv.length(); k++){
            buf[j+1][p2+k] = sv.charAt(k);
        }
        if(p1<p2){
            buf[j+1][p1]  = '/';
        }
        if(p3>p2){
            buf[j+1][p3] = '\\';
        }

        if(left!=null){
            left.printBuf(buf, i, j+2);
        }
        if(right!=null){
            right.printBuf(buf, p2+sv.length(), j+2);
        }
    }
    private int getRootPos(int i) {
        return left==null ? i :i+left.getWidth();
    }




    //中序遍历
    public void midTrav(){
        if(left !=null){//如果左子树不为空,左子树进行中序遍历
            left.midTrav();
        }
        System.out.print(data+" ");
        if(right != null){//如果右子树不为空,右子树进行中序遍历
            right.midTrav();
        }   
    }

    //前序遍历
    public void preTrav(){
        System.out.print(data+" ");
        if(left !=null){//如果左子树不为空,左子树进行前序遍历
            left.preTrav();
        }
        if(right != null){//如果右子树不为空,右子树进行前序遍历
            right.preTrav();
        }
    }

    //后序遍历
    public void postTrav(){
        if(left !=null){//如果左子树不为空,左子树进行后序遍历
            left.postTrav();
        }
        if(right != null){//如果右子树不为空,右子树进行后序遍历
            right.postTrav();
        }
        System.out.print(data+" ");
    }
}
public class Tree {
    public static void main(String[] args) {
        BiTree root = new BiTree(10);
        root = root.add(new BiTree(20));
        root = root.add(new BiTree(30));
        root = root.add(new BiTree(40));
        root = root.add(new BiTree(50));
        root = root.add(new BiTree(60));
        root = root.add(new BiTree(70));
        root = root.add(new BiTree(80));

        /*root.midTrav();
        System.out.println();
        root.preTrav();
        System.out.println();
        root.postTrav();*/

        root.show();
    }
}

二叉树的打印结果:

      |         
  /---40--\     
  |       |     
/-20\   /-60\   
|   |   |   |   
10  30  50  70\ 
              | 
              80
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值