二叉树详解

目录

一、树结构

1、树结构引出

2、关于树的基础概念

二、二叉树

1、二叉树概念

 2、二叉树常见的性质

 3、满二叉树和完全二叉树

 4、二叉树的编号问题

三、二叉树的遍历操作

1、前序遍历

 2、中序遍历

 3、后序遍历

4、层序遍历

5、遍历练习题

四、二叉树遍历实现

 五、相关代码


一、树结构

1、树结构引出

 树结构代表高效的查找与搜索语义

比如说电脑的文件管理器,还有公司的员工图都是采用了树的结构,通过树结构查找会变得十分的快捷

2、关于树的基础概念

       树是一种非线性的数据结构,它是由n (n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
 ●有一个特殊的节点,称为根节点,根节点没有前驱节点
 ●除根节点外,其余节点被分成M(M>0)个互不相交的集合T1、T2、.....Tm,其中每一个集合Ti(1 <= i<=m)又是一棵与树类似的子树。每棵子树的根节点有且只有一个前驱,可以有0个或多个后继
●树是递归定义的

①子树是不相交的

②除了根节点没有前驱节点,其余的每个节点都有且只有一个父节点

③假设树结构中边的个数为x,树节点的个数为n,他们之间的关系是x=n-1

④节点的"度":该节点包含的子树个数

    树的"度":树中最大节点的度

⑤叶子节点:就是度为0的节点(比如上图中的M,J,K节点)

    非叶子节点:就是度不为0的节点,该节点存在子树

⑥根节点:没有前驱节点的节点,一个数只有一个根节点(比如上图的D节点)

⑦节点的层次:从根节点开始计算,对于上图来说,D根节点为第一层,I,J,K节点为第二层,M节点就是第三层

⑧树的高度:当前树中节点层次最大的即为树的高度(上图树的高度就是3)

二、二叉树

1、二叉树概念

树中节点最大的度,为2的数就叫做二叉树,也就是数的度为2的树

①在二叉树中,一个节点最多有两颗子树,二叉树节点的度<=2

②二叉树的有左右之分,且子树的次序不能颠倒,因此二叉树是有序树

 2、二叉树常见的性质

①在深度为K的二叉树中,最多存在2^k -1个节点

②在第K层中,该层最多有2^(k-1)个节点

③假设树结构中边的个数为x,树节点的个数为n,他们之间的关系是x=n-1,通过这个可以推出,度为2的节点(N2)和度为0的节点(N0)之间的关系:

N0=N2+1

 3、满二叉树和完全二叉树

满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是2^k  -1,则它就是满二叉树。
完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。要注意的是满二叉树是一种特殊的完全二叉树。(从视觉上来看,完全二叉树就是满二叉树缺少了右下角)

 4、二叉树的编号问题

 若根节点从1开始编号:若任意一个节点x,既存在子树也存在父节点,,则

该节点的父节点为x/2

左子树的编号为2x

右子树的标号为2x+1

三、二叉树的遍历操作

对于二叉树来说,一共有四种遍历方式

①深度优先遍历(dfs):前序遍历,中序遍历,后序遍历

②广度优先遍历(bfs):   层序遍历

 

1、前序遍历

先访问根节点,然后递归访问左子树,在递归访问右子树(根左右,就是第一次访问该节点就打印,并且第一个节点一定是根节点)

ABDEC

 2、中序遍历

先递归访问根的左子树,然后是根节点,最后是右子树(左根右,就是第二次访问到该节点时就打印,左子树节点都在根节点左侧,右子树节点在根节点右侧)

DBEAC

 3、后序遍历

先递归访问左子树,在递归访问右子树,最后是根节点(左右根,就是第三次访问到该节点时就打印)

DEBCA

4、层序遍历

将二叉树层层访问

ABCDE

5、遍历练习题

 前序遍历:ABDEGHCF

中序遍历:DBGHEACF

后序遍历:DHGEBFCA

层序遍历:ABCDEFGH

四、二叉树遍历实现

package binary_tree;

/**
 * 二叉树的基本操作
 */
class TreeNode<E> {
    //节点值
    E val;
    //左子树的根
    TreeNode<E> left;
    //右子树的根
    TreeNode<E> right;

    public TreeNode(E val) {
        this.val = val;
    }
}

/**
 * 二叉树的建立
 * @param <E>
 */
public class MYbinarytree<E> {

    public TreeNode<Character> root;

    //建立一个简单的二叉树
    public void buildTree(){
        TreeNode<Character> node=new TreeNode<>('A');
        TreeNode<Character> node1=new TreeNode<>('B');
        TreeNode<Character> node2=new TreeNode<>('C');
        TreeNode<Character> node3=new TreeNode<>('D');
        TreeNode<Character> node4=new TreeNode<>('E');
        TreeNode<Character> node5=new TreeNode<>('F');
        TreeNode<Character> node6=new TreeNode<>('G');
        TreeNode<Character> node7=new TreeNode<>('H');
        //连接二叉树
        node.left=node1;
        node.right=node2;
        node1.left=node3;
        node1.right=node4;
        node4.left=node6;
        node6.right=node7;
        node2.right=node5;
        root=node;
    }

    /**
     * 只需要二叉树的根节点,就可以按照前序遍历的方法输出
     * @param root
     */
    public void PreorderTraversal(TreeNode root){
        if (root==null){
            return;
        }
        //根左右,先打印根节点
        System.out.print(root.val+" ");
        //左子树节点的输出交给子函数处理
        PreorderTraversal(root.left);
        //右子树节点的输出交给子函树处理
        PreorderTraversal((root.right));
    }

    /**
     * 只需要二叉树的根节点,就可以按照中序遍历的方法输出
     * @param root
     */
    public void InorderTraversal(TreeNode root){
        if (root==null){
            return;
        }
        //左根右,先递归输出左节点,左节点的输出交给子函数处理
        InorderTraversal(root.left);
        //根节点的输出
        System.out.print(root.val+" ");
        //递归输出右节点,右节点的输出交给子函数处理
        InorderTraversal(root.right);

    }

    /**
     * 只需要二叉树的根节点,就可以按照后序遍历的方法输出
     * @param root
     */
    public void PostordeTraversall(TreeNode root){
        if (root==null){
            return;
        }
        //左右根,先递归输出左节点,左节点的输出交给子函数处理
        PostordeTraversall(root.left);
        //递归输出右节点,右节点的输出交给子函数处理
        PostordeTraversall(root.right);
        //根节点的输出
        System.out.print(root.val+" ");
    }
}

 五、相关代码

任枭雄/rocket_class_ds - Gitee.comhttps://gitee.com/ren-xiaoxiong/rocket_class_ds/tree/master/src/binary_tree

  • 13
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值