Java二叉树

1 树形结构

概念:树是一种非线性的数据结构,它是由n个有限节点组成一个具有层次关系的集合。

  • 特点:
  • 有一个特殊的结点,称为根结点,根结点没有前驱结点;
  • 除根结点外,其余结点被分成 M ( M >0)个互不相交的集合T1、T2........、 Tm ,其中每一个集合又是一棵与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继;
  • 树是递归定义的;
     

子树是不相交的;

除了根结点外,每个结点有且仅有一个父结点;

一棵 N 个结点的树有 N -1条边。

2 二叉树

2.1概念

一棵二叉树是结点的一个有限集合,该集合:
(1)或者为空
(2)或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

注意:
(1)二叉树不存在度大于2的结点
(2)二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树
 

2.2二叉树的性质

  1. 若规定根结点的层数为1,则一棵非空二叉树的第 i 层上最多有2-1( i >0)个结点
  2. 若规定只有根结点的二叉树的深度为1,则深度为 K 的二叉树的最大结点数是2k-1( k >=0)
  3. 对任何一棵二叉树,如果其叶结点个数为n0,度为2的非叶结点个数为n2,则有n0=n2+1。即叶子节点比度为2的节点多一个
  4. 具有 n 个结点的完全二叉树的深度 k 为log2( n +1)上取整
  5. 对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,的结点有:
  • 若 i >0,双亲序号:( i -1)/2; i =0, i 为根结点编号,无双亲结点。
  • 若2i+1< n ,左孩子序号:2i+1,否则无左孩子
  • 若2i+2< n ,右孩子序号:2i+2,否则无右孩子

二叉树的节点=n0+n1+n2; n0=n2+1
 

3 二叉树的遍历

分为:前序遍历、中序遍历、后序遍历、层序遍历

中心思想:本质就是在不同的时机,访问数据。

  1. 前序遍历:先遍历根节点,再遍历左子树,再遍历右子树。
  2. 中序遍历:先遍历左子树,再遍历根节点,再遍历右子树。
  3. 后序遍历:先遍历左子树,再遍历右子树,再遍历根节点。
  4. 层序遍历:从二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第二层的节点,接着是第三层的节点,以次类推,自上而下,自作而右逐层访问树的节点。

例题:写出下图的前序遍历、中序遍历、后序遍历

前序遍历: A B D E H C F G

中序遍历: D B E H A F C G

后序遍历: D H E B F G C A

相关代码如下,注意注释!

import sun.reflect.generics.tree.Tree;

import java.util.ArrayList;
import java.util.List;

public class TestBinaryTree {
    class TreeNode{
        public char val;
        public TreeNode left;
        public TreeNode right;

        //构造方法,构造一个节点
        public TreeNode(char val) {
            this.val = val;
        }
    }

    //运用穷举的方法来写一个二叉树
    public TreeNode creteTree() {
        TreeNode A = new TreeNode('A');
        TreeNode B = new TreeNode('B');
        TreeNode C = new TreeNode('C');
        TreeNode D = new TreeNode('D');
        TreeNode E = new TreeNode('E');
        TreeNode F = new TreeNode('F');
        TreeNode G = new TreeNode('G');
        TreeNode H = new TreeNode('H');

        A.left=B;
        A.right=C;
        B.left=D;
        B.right=E;
        E.right=H;
        C.left=F;
        C.right=G;
        return A;//根节点
    }

    //使用递归来实现
    //前序遍历
    public void preOrder(TreeNode root){
        if(root==null){
            return;
        }
        System.out.print(root.val+" ");
        preOrder(root.left);
        preOrder(root.right);
    }

    
    //中序遍历
    public void inOrder(TreeNode root){
        if(root==null){
            return;
        }
        inOrder(root.left);
        System.out.print(root.val+" ");
        inOrder(root.right);
    }

    //后序遍历
    public void postOrder(TreeNode root){
        if(root==null){
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.val+" ");
    }

    public static int count=0;
    //获取数中节点的个数 遍历思路
    public void size1(TreeNode root){
        if(root==null){
            return ;
        }
        count++;
        //遍历这个二叉树
        size1(root.left);
        size1(root.right);
    }

    //子问题的思路
    //整个树的节点=左树节点+右数节点+1
    public int size2(TreeNode root){
        if(root==null){
            return 0;
        }
        //root不为空
        int tmp=size2(root.left)+size2(root.right)+1;
        return tmp;
    }

    public static int leafCount=0;
    //获取叶子节点的个数  遍历思路
    void getLeafNodeCount1(TreeNode root){
        if(root==null){
            return;
        }
        if(root.left==null && root.right==null){
            leafCount++;
        }
        getLeafNodeCount1(root.left);
        getLeafNodeCount1(root.right);
    }

    //子问题思路
    int getLeafNodeCount2(TreeNode root){
        if(root==null){
            return 0;
        }
        if(root.left==null && root.right==null){
            return 1;
        }
        int tmp=getLeafNodeCount2(root.left)+getLeafNodeCount2(root.right);
        return tmp;
    }
    //获取第K层节点的个数
    int getKLevelNodeCount(TreeNode root,int k){
        if(root==null){
            return 0;
        }
        if(k==1){
            return 1;
        }
        return getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);
    }

    //获取二叉树的高度(二叉树的最大深度)
    //整个树的高度=左树和右树高度的最大值+1
    int getHeight(TreeNode root){
        if(root==null){
            return 0;
        }
        int leftH=getHeight(root.left);
        int leftR=getHeight(root.right);
        return leftH>leftR ? leftH+1 : leftR+1;
    }

    //检测值为value的元素是否存在
    TreeNode find(TreeNode root,int val){
        if(root==null){
            return null;
        }
        if(root.val==val){
            return root;
        }
        TreeNode ret=find(root.left,val);
        if(ret !=null){
            return ret;
        }
        ret=find(root.right,val);
        if(ret !=null){
            return ret;
        }
        return null;
    }

//判断一棵树是不是完全二叉树
    boolean isCompleteTree(TreeNode root){
        Queue<TreeNode> queue=new LinkedList<>();
        if(root!=null){
            queue.offer(root);//root不为空把root放队列(queue)中
        }
        while(!queue.isEmpty()){
            //队列不为空,弹出一个元素给cur
            TreeNode cur=queue.poll();
            if(cur!=null){//cur不为空把cur的左右带入队列
                queue.offer(cur.left);
                queue.offer(cur.right);
            }else{
                break;
            }
        }

        while (!queue.isEmpty()){
            TreeNode cur=queue.peek();
            if(cur!=null){
                return false;
            }else {
                queue.poll();//弹出
            }
        }
        return true;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值