(5)二叉树

来源:互联网 发布:荒潮 知乎 编辑:程序博客网 时间:2024/06/06 15:44

二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”,左子树和右子树同时也是二叉树。
二叉树若直接定义可能会造成畸形,对树畸形的改进一般有两种方法,
- 方法一:平衡二叉树。
- 方法二:红黑树。
对平衡二叉树的定义:左右子树的高度相差不超过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
原创粉丝点击