当前位置:   article > 正文

Java数据结构 | 二叉树的基本操作_二叉树的基本操作java

二叉树的基本操作java

 

目录

一、二叉树的存储方式

二、二叉树的遍历

前序遍历

中序遍历

后序遍历 

层序遍历

 三、二叉树的其他操作

获取树中节点的个数

获取树中叶子节点的个数

获取第k层节点的个数

获取二叉树的深度


一、二叉树的存储方式

二叉树可以链式存储,也可以顺序存储。

那么链式存储方式就用指针, 顺序存储的方式就是用数组。

顾名思义就是顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在散落在各个地址的节点串联一起。

链式存储如图:

2020092019554618.png

链式存储是大家很熟悉的一种方式,那么我们来看看如何顺序存储呢?

其实就是用数组来存储二叉树,顺序存储的方式如图:

20200920200429452.png

用数组来存储二叉树如何遍历的呢?

如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。

但是用链式表示的二叉树,更有利于我们理解,所以一般我们都是用链式存储二叉树。

所以大家要了解,用数组依然可以表示二叉树。

二、二叉树的遍历

如果按照某种规则进行约定,则每个人对于同一棵树的遍历结果肯定是相同的。如果N代表根节点,L代表根节点的左子树,R代表根节点的右子树,则根据遍历根节点的先后次序有以下遍历方式:

NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点--->根的左子树--->根的右子树。 LNR:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树。 LRN:后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点

层序遍历:从二叉树的根节点出发,首先访问第一层的节点,然后从左至右访问第二层的节点,从上至下,以此类推

2927fa11a020709ef043b39bb6e7a00f.png

以上树为例,简单介绍二叉树的遍历实现:

  • 前序遍历

根节点-左子树-右子树

db8f1581f365b16f23c1a515139bd570.png

前序遍历的结果为: A B D E H C F G

  1. //前序遍历
  2.   public void preOrder(TreeNode root){
  3.        if(root == null){
  4.            return;
  5.       }
  6.        System.out.println(root.val+" ");
  7.        preOrder(root.left);
  8.        preOrder(root.right);
  9.   }

左子树-根节点-右子树

03423b17d4d891cf3733bfc1b1bcfac8.png

中序遍历的结果为: D B E  H A F C G 

  1. // 中序遍历
  2.   public void inOrder(TreeNode root){
  3.       if(root == null){
  4.           return;
  5.       }
  6.       inOrder(root.left);
  7.       System.out.println(root.val+" ");
  8.       inOrder(root.right);
  9.   }

左子树-右子树-根节点

6684927873e41536f821f9f736f1aa77.png

  1. // 后序遍历
  2.   public void postOrde(TreeNode root){
  3.       if(root == null){
  4.           return;
  5.       }
  6.       postOrde(root.left);
  7.       postOrde(root.right);
  8.       System.out.println(root.val+" ");
  9.   }
  • 层序遍历

从根节点出发从左至右,以此类推

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

二叉树后序遍历的特点:最后一个节点肯定是根节点。

二叉树先序遍历的特定:第一个节点肯定是根节点。

  • 使用List存储节点元素进行前序遍历

  1.  public List<Character> preOrder2(TreeNode root){
  2.        List<Character> ret = new ArrayList<>();
  3.        if(root == null){
  4.            return ret;
  5.       }
  6.        ret.add(root.val);
  7.        List<Character> leftTree = preOrder2(root.left);
  8.        ret.addAll(leftTree);
  9.        List<Character> rightTree  = preOrder2(root.right);
  10.        ret.addAll(rightTree);
  11.        return ret;
  12.   }

 三、二叉树的其他操作

  • 获取树中节点的个数

获取树中节点的个数,我们可以采用遍历的方法实现,也可以采用子问题的思路,使用递归的方法,即左子树+右子树+根节点(+1)即可实现

size(root.left) +size(root.right)+1; 
  1.   /**
  2.     * 遍历方法
  3.     */
  4.    public static int nodeSize = 0;
  5.    public int size(TreeNode root){
  6.        if(root == null){
  7.            return 0;
  8.       }
  9.        nodeSize++;
  10.        size(root.left);
  11.        size(root.left);
  12.        return nodeSize;
  13.   }
  14.    /**
  15.     * 子树相加再加上根节点
  16.     * @param root
  17.     * @return
  18.     */
  19.    public int size2(TreeNode root){
  20.        if(root == null){
  21.            return 0;
  22.       }
  23.        int tmp = size(root.left) +size(root.right)+1;
  24.        return tmp;
  25.   }
  • 获取树中叶子节点的个数

获取树中叶子节点的个数,即左子树和右子树都为空时root.left==null&&root.right==null时,左子树上叶子节点+右子树上所有的叶子节点 或者使用临时变量leafSize++;

  1. /**
  2.     * 获取叶子节点的个数
  3.     * @param root
  4.     * @return
  5.     */
  6. //子问题思路
  7.   public int getLeafNodeCount(TreeNode root){
  8.       if(root == null){
  9.           return 0;
  10.       }
  11.       if(root.left==null&&root.right==null){
  12.           return 1;
  13.       }
  14.       int tmp = getLeafNodeCount(root.left)+getLeafNodeCount(root.right);
  15.       return tmp;
  16.   }
  17.     //遍历方法
  18.   public static int leafSize = 0;
  19.   public int getLeafNodeCount2(TreeNode root){
  20.       if(root == null){
  21.           return 0;
  22.       }
  23.       if(root.left == null&&root.right == null){
  24.           leafSize++;
  25.       }
  26.       getLeafNodeCount2(root.left);
  27.       getLeafNodeCount2(root.right);
  28.       return leafSize;
  29.   }
  • 获取第k层节点的个数

求第k层节点的个数,可以转化为左树的 k-1 层 + 右树的k -1 层,即

当K=3时,转化为左树的第 2层和右树的第2层的节点个数,最后转化为当 k = 1时,返回左数第二层的节点2和右数第二层的节点2相加即可得到 第3 层的节点个数为4

bb22f911fdc14fc58aec800a1719adb5.png

  1. public int getKLevelNodeCount(TreeNode root,int k){
  2.        if(root == null|| k <= 0){
  3.            return 0;
  4.       }
  5.        if(k==1){
  6.            return 1;
  7.       }
  8.     int tmp = getKLevelNodeCount(root.left,k-1)+getKLevelNodeCount(root.right,k-1);
  9.      return tmp;
  10.   }
  • 获取二叉树的深度

  1. public 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.        //左右子树的最大c
  8.        return leftHeight > rightHeight ? leftHeight+1 : rightHeight +1;
  9.   }

 

ced485cbb11e458d81a746890b32cf3f.gif

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/878990
推荐阅读
相关标签
  

闽ICP备14008679号