• 数据结构——新手村级二叉树讲解


    目录

    一,树型结构

    1.什么是树型结构

    2.基础概念

    3.树的表示形式(了解)

    二,二叉树

    1.什么是二叉树

     2.两种特殊的二叉树

     3.二叉树的性质

    4.二叉树的存储

    (1).顺序存储

    (2).链式存储

    5.二叉树的遍历

    (1).什么是遍历

    (2).前序遍历

    (2).中序遍历

    (3).后序遍历

    (4).层序遍历

    (5).二叉树的基本操作


    一,树型结构

    1.什么是树型结构

    树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是朝上,而朝下的。

    特点:

    (1).有一个特殊的结点,称为根结点,根结点没有前驱结点

    (2).除根结点外,其余结点被分成M(M > 0)个互不相交的集合T1、T2、......、Tm,其中每一个集合 Ti (1 <= i<= m) 又是一棵与树类似的子树。

    (3).每棵子树的根结点有且只有一个前驱,可以有0个或多个后继

    (4).树是递归定义的

    (5).子树之间不能有交集,否则就不是树形结构

     

    2.基础概念

    结点的度:一个结点含有子树的个数称为该结点的度; 如上图:A的度为6
    树的度:一棵树中,所有结点度的最大值称为树的度; 如上图:树的度为6
    叶子结点或终端结点度为0的结点称为叶结点; 如上图:B、C、H、I...等节点为叶结点
    双亲结点或父结点:若一个结点含有子结点,则称其为子结点的父结点; 如上图:A是B的父结点
    孩子结点或子结点:一个结点其下的结点,为该结点的子结点; 如上图:B是A的子结点
    根结点:一棵树中,没有双亲结点的结点;如上图:A
    结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推
    树的高度或深度:树中结点的最大层次; 如上图:树的高度为4
    ———————————————————了解即可————————————————————
    非终端结点或分支结点度不为0的结点; 如上图:D、E、F、G...等节点为分支结点
    兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点
    堂兄弟结点双亲在同一层的结点互为堂兄弟;如上图:H、I互为兄弟结点
    结点的祖先:根结点;如上图:A是所有结点的祖先
    子孙:除根结点以外的结点。如上图:所有结点都是A的子孙
    森林:由m(m>=0)棵互不相交的树组成的集合称为森林

    3.树的表示形式(了解)

    了解:双亲表示法,孩子表示法、孩子双亲表示法

    常用:孩子兄弟表示法

    class Node {
      int value; // 树中存储的数据
      Node firstChild; // 第一个孩子引用
      Node nextBrother; // 下一个兄弟引用
    }

    二,二叉树

    1.什么是二叉树

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

     2.两种特殊的二叉树

    1. 满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。                满二叉树是一种特殊的完全二叉树。


    2. 完全二叉树:设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,且第h层的叶子结点都是从左到右依次排布的                                                                                        完全二叉树是由满二叉树而引出来的,效率更高,堆排序的数据结构即完全二叉树。

     3.二叉树的性质

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

    4.二叉树的存储

    二叉树的存储结构分为:顺序存储链式存储

    (1).顺序存储

    指使用顺序表(数组)存储二叉树,此存储方法只适用于完全二叉树

    对于一般二叉树,若使用该存储方式,需要添加一些不存在的空结点

     排序为A B C D E F G H I J

    (2).链式存储

    通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式

    二叉链至少包含:左指针域lchild、数据域data、右指针域rchild

    // 孩子表示法
    class Node {
      int val; // 数据域
      Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
      Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
    }
    // 孩子双亲表示法
    class Node {
      int val; // 数据域
      Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
      Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
      Node parent;   // 当前节点的根节点
    }

    5.二叉树的遍历

    (1).什么是遍历

    遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。

    (2).前序遍历

    前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树

     前序遍历结果:1 2 3 4 5 6

    void preOrder(TreeNode root){

          if(root==null) return ;

          System.out.print(root.val+" ");

          preOrder(root.left);

          preOrder(root.right);

    }

    (2).中序遍历

    中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树

     中序遍历结果:3 2 1 5 4 6

    void inOrder(TreeNode root){

          if(root==null) return ;

          inOrder(root.left);

          System.out.print(root.val+" ");

          inOrder(root.right);

    }

    (3).后序遍历

    后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点

     后序遍历结果:3 1 5 6 4 1

    void postOrder(TreeNode root){

          if(root==null) return ;

          postOrder(root.left);

          postOrder(root.right);

          System.out.print(root.val+" ");   

    }

    (4).层序遍历

    自上而下,自左至右逐层访问树的结点的过程

     层序遍历结果:A B C D E F G H I

    利用队列先进先出的性质

    void levelOrder(TreeNode root){
        if(root==null) return ;
        Queue queue=new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            TreeNode cur=queue.poll();
            System.out.println(cur.val+" ");
            if(cur.left!=null){
                queue.offer(cur.left);
            }
            if(cur.right!=null){
                queue.offer(cur.right);
            }
        }
    }

    (5).二叉树的基本操作

    先实现一个TreeNode类,用于后面的使用

    1. import java.util.*;
    2. public class TreeNode {
    3. public char val;
    4. public TreeNode left;
    5. public TreeNode right;
    6. private TreeNode root;
    7. public TreeNode(char val) {
    8. this.val = val;
    9. }
    10. public void createTree() {
    11. TreeNode A = new TreeNode('A');
    12. TreeNode B = new TreeNode('B');
    13. TreeNode C = new TreeNode('C');
    14. TreeNode D = new TreeNode('D');
    15. TreeNode E = new TreeNode('E');
    16. TreeNode F = new TreeNode('F');
    17. TreeNode G = new TreeNode('G');
    18. TreeNode H = new TreeNode('H');
    19. A.left = B;
    20. A.right = C;
    21. B.left = D;
    22. B.right = E;
    23. C.left = F;
    24. C.right = G;
    25. E.right = H;
    26. this.root = A;
    27. }

    1.获取树中叶子结点数

    1. public static int leafSize;
    2. int getLeafNodeCount(TreeNode root) {
    3. if(root==null){
    4. return 0;
    5. }
    6. if(root.left==null&&root.right==null){
    7. return 1;
    8. }
    9. return getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
    10. }

    2.获取树中结点数

    1. int getLeafSize(TreeNode root) {
    2. if(root==null){
    3. return 0;
    4. }
    5. if(root.left==null&&root.right==null){
    6. leafSize++;
    7. }
    8. getLeafNodeCount2(root.left);
    9. getLeafNodeCount2(root.right);
    10. return leafSize;
    11. }

    3.获取树的高度

    1. int getHeight(TreeNode root){
    2. if(root==null){
    3. return 0;
    4. }
    5. int leftHeight=getHeight(root.left);
    6. int rightHeight=getHeight(root.right);
    7. int max=leftHeight>rightHeight?leftHeight:rightHeight;
    8. return max+1;
    9. }

    4.检测val的元素是否存在

    1. TreeNode find(TreeNode root ,int val){
    2. if(root==null)return null;
    3. if(root.val==val){
    4. return root;
    5. }
    6. TreeNode ret1=find(root.left,val);
    7. if(ret1!=null){
    8. return ret1;
    9. }
    10. TreeNode ret2=find(root.right,val);
    11. if(ret2!=null){
    12. return ret2;
    13. }
    14. return null;
    15. }

    5.判断是否为完全二叉树

    1. boolean isCompleteTree(TreeNode root){
    2. if(root==null) return true ;
    3. Queue queue=new LinkedList<>();
    4. queue.offer(root);
    5. while(!queue.isEmpty()){
    6. TreeNode cur=queue.poll();
    7. if(cur!=null){
    8. queue.offer(cur.left);
    9. queue.offer(cur.right);
    10. }else break;
    11. }
    12. while(!queue.isEmpty()){
    13. TreeNode cur=queue.poll();
    14. if(cur!=null){
    15. return false;
    16. }else{
    17. queue.poll();
    18. }
    19. }
    20. return true;
    21. }

  • 相关阅读:
    08.29web自动化测试
    idea代码快捷键Mac版
    haproxy参数选择问题
    LeetCode高频题互联网大厂笔试题:手撕k-means聚类算法:python代码实现
    WRF4.2安装过程全记录
    map和set
    解密 docker 容器内 DNS 解析原理
    二叉查找树迭代器
    SSM-spring注解式缓存redis
    一刷完结撒花
  • 原文地址:https://blog.csdn.net/weixin_63056061/article/details/125987275