Java二叉树学习

①二叉树的定义:

节点:在Java当中,为一个对象,拥有left和right两个属性,左节点用来存放左值,右节点用来存放右枝。

如图为一个简易 的二叉树构图

②完全二叉树、满二叉树的概念

完全二叉树:定义:节点存放的顺序为从上到下从左到右依次存储,中间不能存在空隙。

例如如下:

举一个非完全二叉树的例子:

 此时,由于左下角的第二个箭头没有指向,任何一个节点,因此此二叉树就不是完全二叉树

 ③二叉树的层数定义:根节点到最远处的节点的最短路径(包含根节点和最远的节点)。

如上图,二叉树的层数就是3。

④满二叉树:在二叉树当中,第k层的节点数为2的(k-1)次方。因此,k层的二叉树,总的节点数为2的0次方+2的1次方+2的2次方+......+2的k-1次方等于2的k次方-1.

即:任意一层都是满的的二叉树。

⑤二叉树的一些常用结论,术语:

         叶子节点:一棵二叉树的某个节点,如果它既没有左枝,又没有右枝,那么这个节点就是叶子节点。

       节点的度:一个节点往下有几条边,那么就称这个节点的度是几。

          (1)对于任意一颗二叉树,有n个节点,就有n-1条边

          (2)对于任意一棵完全二叉树,度为0的节点的数量等于度为2的节点的数量+1。

     推导过程:

         假设一棵二叉树有N个节点,那么N=n0+n1+n2;n0度为0的节点,n1为度为1的节点,n2为度为2的节点。

        根据二叉树的性质可以得知:二叉树度为0的节点可以产生0条边,边为1的节点可以产生1条边,边为2的节点可以产生2条边,那么,总的边数为n0*0+n1*1+n2*2;

因此,根据1结论可以得知:n0+n1+n2-1=n1+2*n2;

化简得到:n0=n2+1;

        (3)在具有2*n个节点的完全二叉树当中,叶子节点的个数为n。

         根据完全二叉树的定义可以推到出来,在完全二叉树当中,当边数为1的节点存在时候,完全二叉树的节点总数为n0+1+n2;假设叶子节点个数为n0,度数为2的节点个数为n2。因此可以得出:

2*n=n0+1+n2;2*n=n0+1+n0-1;2*n=2*n0;即:n=n0;那么叶子节点的个数就是n。

       那么当完全二叉树节点为基数时候呢?同理,可以得出答案:N=n0+n0-1;n0=(N+1)/2;

     (4)具有N个节点的完全二叉树的深度为log2(n+1)向上取整。

⑥二叉树的遍历

第一种遍历方式:根--->左--->右

思路:从跟出发,先遍历左枝,再遍历右枝:

实现:A-->B-->D-->C-->E-->F。

代码实现:

 /**
     * 前序遍历
     * 根节点@param root
     */
    public void preOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }

 第二种遍历方式:中序遍历:

左--->根--->右:回到上图:

顺序为:D-->B-->A-->E-->C-->F

代码实现:

/**
     * 中序遍历
     * 根节点@param root
     */
    public void infixOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        infixOrder(root.left);
        System.out.println(root.val);
        infixOrder(root.right);
    }

第三种遍历方式:左-->右-->根

D-->B-->E-->F-->C-->A

代码实现

/**
     * 后序遍历
     * 根节点@param root
     */
    public void afterOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        afterOrder(root.left);
        afterOrder(root.right);
        System.out.println(root.val);
    }

递归:返回到上一个方法里面调用此方法的位置。

来一道题目:

假设一棵二叉树的中序遍历是:badce,后序遍历是:bdeca;

求前序遍历:

第一步:寻找到根节点:

已知:后序遍历最后遍历的是根节点,因此a为二叉树的根节点。然后再看中序遍历的结果:

a的左边为左树,右边为右树。

再看后序遍历的结果,c位于a的上一个位置,因此c为一个根,那么此时就可以绘制出来一个二叉树的头三个节点:a为根节点,b为a的左节点,c为a的右节点,再根据遍历的顺序判断,d为c的左节点,e为c的右节点

    再来一道题目:

已知一棵二叉树的先序遍历为E->F->H->I->G-->J-->K;

中序遍历为:H-->F-->I-->E-->J-->K-->G;

画出这一棵二叉树:由题目可知:E为根节点,HFI为左树,JKG为右数

中序遍历:谁的左枝先为空,就先输出谁。

因此可以判定:在左数部分:H的左枝为NULL,因此H被先输出,然后再返回调用左枝的节点,即:F节点,输出F的值,接着,输出完成之后,由于F的右枝不为NULL,因此,可以往右走,走完之后,由于右枝(I)的左枝为NULL,因此返回上一个节点(I),并且输出I的值...

那么,树的右枝同样道理。

 

    

          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值