当前位置: 首页 > wzjs >正文

团购网站设计武汉网站提升排名

团购网站设计,武汉网站提升排名,英国做电商网站,做除尘环保的如何推广自己的网站目录 树型结构(了解) 概念 概念(重要) 树的表示形式(了解) 树的应用 二叉树(重点) 概念 两种特殊的二叉树 二叉树的性质 利用性质做题(关键) 二叉…

目录

树型结构(了解)

概念

概念(重要)

树的表示形式(了解)

树的应用

二叉树(重点)

概念

两种特殊的二叉树

二叉树的性质

利用性质做题(关键)

二叉树的存储

二叉树的基本操作

前置说明

二叉树的遍历

二叉树的基本操作

面试题


树型结构(了解)

概念

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

它具有以下的特点:

·有一个特殊的结点,称为根结点,根结点没有前驱结点

·除根结点外,其余结点被分成M(M > 0)个互不相交的集合T1、T2、......、Tm,其中每一个集合Ti (1<=i<=m)又是一棵与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继

·树是递归定义的。

注:

1.子树是不相交的;

2.除根节点外,每个结点有且仅有一个父节点

3.一颗N个节点的树有N-1条边

概念(重要)

结点的度:一个结点含有子树的个数称为该结点的度; 如上图:A的度为6【因为A下面有B,C,D,E,F,G这六个节点,所以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)棵互不相交的树组成的集合称为森林


树的表示形式(了解)

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,如:双亲表示法, 孩子表示法、孩子双亲表示法、孩子兄弟表示法等等。我们这里就简单的了解其中最常用的孩子兄弟表示法

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

其表示方法如下图所示

树的应用

文件系统管理(目录和文件)


二叉树(重点)

概念

一棵二叉树是结点的一个有限集合,该集合:

1. 或者为

2. 或者是由一个根节点加上两棵别称为左子树右子树的二叉树组成。

从上图可以看出:

1. 二叉树不存在度大于2的结点【重要

2. 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树 注意:对于任意的二叉树都是由以下几种情况复合而成的:


两种特殊的二叉树

1. 满二叉树: 一棵二叉树,如果每层的结点数都达到最大值,则这棵二叉树就是满二叉树。也就是说,如果一棵 二叉树的层数为K,且结点总数是2^k-1,则它就是满二叉树

2. 完全二叉树: 完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从0至n-1的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。【从上到下,从左到右依次存放】

二叉树的性质

1. 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多2^(i-1)(i>0)个结点

2. 若规定只有根结点的二叉树的深度为1,则深度为K的二叉树的最大结点数是2^k-1 (k>=0)

3. 对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0=n2+1【对于任何一颗二叉树,叶子节点的个数永远比度为2的节点个数多1】

推导一颗N个节点的树有N-1条边

在任意一颗二叉树中,叶子节点的个数为n0,度为1的结点个数为n1,度为2的节点个数为n2,则会产生总的结点个数:N = n0+n1+n2;且度为0的节点向下不会产生边,度为1的节点向下会产生n1条边,度为2的节点向下会产生2*n2条边,总共产生的边数:N-1=n1+2*n2; 将两个式子联立即可得出答案。

4. 具有n个结点完全二叉树深度klog2(n+1)上取整

5. 对于具有n个结点的完全二叉树,如果按照从上至下左至右的顺序对所有节点从0开始编号,则对于序号为i 的结点有:

·若i>0,双亲序号:(i-1)/2;i=0,i为根结点编号,无双亲结点

·若2i+1<n,左孩子序号:2i+1,否则无左孩子

·若2i+2<n,右孩子序号:2i+2,否则无右孩子

利用性质做题(关键)

以下是小编写的一个题解


二叉树的存储

二叉树的存储结构分为:顺序存储类似于链表的链式存储

二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式,具体如下:主要以孩子表示法为主

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

二叉树的基本操作

前置说明

在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结 构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等 二叉树结构了解的差不多时,我们反过头再来研究二叉树真正的创建方式。

以上述这个二叉树为例子,即创建像上面这个二叉树;

package BinaryTree;/*** 这里手动创建一个二叉树*/
public class BinaryTree1 {// 树是由一个个节点构成的,所有得先把这个节点给构造出来static class TreeNode{private char val;  // 值private TreeNode left;  // 左孩子private TreeNode right; // 右孩子/*再来一个构造方法*/public TreeNode(char val) {this.val = val;}}/*** 还是像刚刚学习链表一样,我们用最淳朴得方法来创建一个二叉树*/public TreeNode createTree(){TreeNode node1 = new TreeNode('A');TreeNode node2 = new TreeNode('B');TreeNode node3 = new TreeNode('C');TreeNode node4 = new TreeNode('D');TreeNode node5 = new TreeNode('E');TreeNode node6 = new TreeNode('F');TreeNode node7 = new TreeNode('G');TreeNode node8 = new TreeNode('H');node1.left = node2;node1.right = node3;node2.left = node4;node2.right = node5;node5.right = node8;node3.left = node6;node3.right = node7;return node1;  // 返回根节点}}

二叉树的遍历

约定的遍历方式:

前序遍历(先序遍历)——访问根结点--->根的左子树--->根的右子树。【根、左、右

中序遍历——根的左子树--->根节点--->根的右子树。【左、根、右

后序遍历——根的左子树--->根的右子树--->根节点。【左、右、根

层序遍历:除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。设二叉树的根节点所在 层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层 上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

前序遍历代码展示:

public  void preOrder(TreeNode root){// root节点一直再变化// 当root节点为空,说明已经打印完了if (root == null){return;}System.out.print(root.val+" ");preOrder(root.left);  // 走完根就先走左边preOrder(root.right); //走完左边就走右边}

中序遍历代码展示:

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

后序遍历代码展示:

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

【练习】请同学们根据以上二叉树的三种遍历方式,给出以下二叉树的:

答案:

前:ABDEHCFG

中:DBEHAFCG

后:DHEBFGCA

选择题:

解析:


二叉树的基本操作

代码展示:

package BinaryTree;import java.util.ArrayList;
import java.util.List;import static java.lang.Math.max;/*** 这里手动创建一个二叉树*/
public class BinaryTree1 {// 树是由一个个节点构成的,所有得先把这个节点给构造出来static class TreeNode{private char val;  // 值private TreeNode left;  // 左孩子private TreeNode right; // 右孩子/*再来一个构造方法*/public TreeNode(char val) {this.val = val;}}/*** 还是像刚刚学习链表一样,我们用最淳朴得方法来创建一个二叉树*/public TreeNode createTree(){TreeNode node1 = new TreeNode('A');TreeNode node2 = new TreeNode('B');TreeNode node3 = new TreeNode('C');TreeNode node4 = new TreeNode('D');TreeNode node5 = new TreeNode('E');TreeNode node6 = new TreeNode('F');TreeNode node7 = new TreeNode('G');TreeNode node8 = new TreeNode('H');node1.left = node2;node1.right = node3;node2.left = node4;node2.right = node5;node5.right = node8;node3.left = node6;node3.right = node7;return node1;  // 返回根节点}/*** 前序遍历* @param root*/public  void preOrder(TreeNode root){// root节点一直再变化// 当root节点为空,说明已经打印完了if (root == null){return;}System.out.print(root.val+" ");preOrder(root.left);  // 走完根就先走左边preOrder(root.right); //走完左边就走右边}/*** 前序遍历得升级:将前序遍历的结果存储到list当中*/public List<TreeNode> preOrder2(TreeNode root){List<TreeNode> list = new ArrayList<>();if (root == null){return list;}list.add(root);List<TreeNode> leftTree = preOrder2(root.left);list.addAll(leftTree);List<TreeNode> rightTree = preOrder2(root.left);list.addAll(rightTree);return list;}/*** 中序遍历* @param root*/public void inOrder(TreeNode root){if (root == null){return;}inOrder(root.left);System.out.print(root.val + " ");inOrder(root.right);}/*** 后序遍历* @param root*/void postOrder(TreeNode root){if (root == null){return;}postOrder(root.left);postOrder(root.right);System.out.print(root.val + " ");}public int size = 0;/*** 获取树中节点的个数** 思路1:* 以前序遍历/中序遍历/后序遍历 遍历这棵树的时候,* 每个节点都会遍历到,遍历一次节点我们就计数一次** 思路2:子问题思路* 要算当前root总共有多少个节点,其实就等于=左数的节点的个数+右树的节点的个数+1** @param root* @return*/public int size(TreeNode root){if (root == null){return 0;  // 如果树为空【即为0个节点】}size++;size(root.left);size(root.right);return size;}public int size1(TreeNode root){if (root == null){return 0;  // 如果树为空【即为0个节点】}return size1(root.left)+size1(root.right)+1;}public int leafSize = 0;/*** 获取叶子节点的个数* 思路1:* 先遍历【前序/中序/后序都行】* 如果root左右都为空,说明他就是一个叶子** 思路2:子问题的思路* 要求当前root有多少个节点,其实就相当于求root左树的叶子+root右树的叶子=整一棵树的叶子* @param root* @return*/public void getLeafNodeCount(TreeNode root){// 如果它是一棵空树,就什么都不做if (root == null){return;}// 如果他不为空就要判断根节点左右是不是都为空,都为空则加1if (root.left == null && root.right == null){leafSize++;}getLeafNodeCount(root.left);getLeafNodeCount(root.right);}public int getLeafNodeCount2(TreeNode root){// 如果它是一棵空树,就什么都不做if (root == null){return 0;}if (root.left == null && root.right == null){return 1;}return getLeafNodeCount2(root.left)+getLeafNodeCount2(root.right);}/*** 获取第K层节点的个数* @param root* @param k* @return* 思路1:遍历* 思路2:子问题* root这棵树的第K层 = root.left的K-1层 + root.right的K-1层***/public int getKLevelNodeCount(TreeNode root,int k){if (root == null){return 0;}if (k==1){//到达第K层return 1;}return getKLevelNodeCount(root.left, k-1)+getKLevelNodeCount(root.right,k-1);}/*** 获取二叉树的高度* @param root* @return* 思路:子问题思路* root这棵树的高度就是 root左树这棵树和root右树这棵树的最大值*/public int getHeight(TreeNode root){// 如果这棵树是一颗空树,自然就没有深度了if (root == null){return 0;}return max(getHeight(root.left),getHeight(root.right))+1;}/*** 检测值为value的元素是否存在* @param root* @param val* @return* 思路1:以前序遍历的方式进行遍历*/public boolean find(TreeNode root, char val){if (root == null){return false;}if (root.val == val){return true;}boolean leftVal = find(root.left,val);  // 先去我的左树找if (leftVal == true){return true;}//  如果我的左树找不到再去我的右树找boolean rightVal = find(root.right,val);  // 先去我的右树找if (rightVal == true){return true;}return false;}/***  层序遍历*/public void levelOrder(TreeNode root){}/*** 判断一棵树是不是完全二叉树* @param root* @return*/public boolean isCompleteTree(TreeNode root){return false;}}

测试代码:

package BinaryTree;
/*** 这个代码下主要是二叉树的一个方法的测试*/
public class Test {public static void main(String[] args) {BinaryTree1 binaryTree1 = new BinaryTree1();   // 实例化一个二叉树对象BinaryTree1.TreeNode root = binaryTree1.createTree();   // 创建一个二叉树对象,返回根节点System.out.println("=============");binaryTree1.preOrder(root);System.out.println();  // 来一个回车binaryTree1.inOrder(root);System.out.println();binaryTree1.postOrder(root);System.out.println();System.out.println("=============");/*** 下面是一些二叉树的一些常规操作的代码*/// 1.测试节点个数int size = binaryTree1.size(root);System.out.println("该二叉树的节点树为:"+size);int size1 = binaryTree1.size1(root);System.out.println("该二叉树的节点树为:"+size1);System.out.println("=============");// 2.测试叶子节点个数binaryTree1.getLeafNodeCount(root);System.out.println("该二叉树叶子节点的个数:"+binaryTree1.leafSize);System.out.println("该二叉树叶子节点的个数:"+binaryTree1.getLeafNodeCount2(root));System.out.println("=============");// 3.测试第K层有多少个节点int count = binaryTree1.getKLevelNodeCount(root, 2);System.out.println("该二叉树第2层的节点个数:"+count);System.out.println("=============");// 4.测试一下这棵树的高度int hight = binaryTree1.getHeight(root);System.out.println("该二叉树的高度为:"+hight);System.out.println("=============");// 5.检测值为value的元素是否存在boolean result1 = binaryTree1.find(root,'E');if (result1 == true){System.out.println("在该二叉树中找到了这个节点");}else {System.out.println("该二叉树中没有这个节点");}boolean result2 = binaryTree1.find(root,'Z');if (result2 == true){System.out.println("在该二叉树中找到了这个节点");}else {System.out.println("该二叉树中没有这个节点");}}}

面试题

1. 检查两颗树是否相同 100. 相同的树 - 力扣(LeetCode)

何为相同:如果两棵树在结构上是相同的,而且节点上的值也是相同的

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {// 如果一个为空,另外一个不为空,则这两颗树一定是不相等的if(q != null && p == null || q == null && p != null){return false;}// 两个都为空if(q == null && p == null){return true;}// 如果两个都不为空呢if(p.val != q.val){return false;}return isSameTree(q.left,p.left) && isSameTree(p.right,q.right);}
}

2. 另一颗树的子树

572. 另一棵树的子树 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {/**这个代码是判断两棵树是不是一个相同的树*/public boolean isSameTree(TreeNode p, TreeNode q) {// 如果一个为空,另外一个不为空,则这两颗树一定是不相等的if(q != null && p == null || q == null && p != null){return false;}// 两个都为空if(q == null && p == null){return true;}// 如果两个都不为空呢if(p.val != q.val){return false;}return isSameTree(q.left,p.left) && isSameTree(p.right,q.right);}public boolean isSubtree(TreeNode root, TreeNode subRoot) {if(root == null){return false;}// 如果只有一个节点if(isSameTree(root,subRoot)){return true;}if(isSubtree(root.left,subRoot)){return true;}if(isSubtree(root.right,subRoot)){return true;}return false;}
}

注:写这种遍历题的时候,需要注意“空指针异常


3. 翻转二叉树

226. 翻转二叉树 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode invertTree(TreeNode root) {// 如果该树为空if (root == null) {return null;}// 交换左右子树TreeNode temp = root.left;root.left = root.right;root.right = temp;// 递归反转左右子树invertTree(root.left);invertTree(root.right);return root;}
}

4. 判断一颗二叉树是否是平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode)

核心思路:只有每一颗子树都是高度平衡的,才能说这棵树是高度平衡的

代码示例1:效率较低

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int getHeight(TreeNode root){// 如果这棵树是一颗空树,自然就没有深度了if (root == null){return 0;}return Math.max(getHeight(root.left), getHeight(root.right)) + 1;}public boolean isBalanced(TreeNode root) {// 如果是空树,就一定是一颗平衡树if(root == null){return true;}if(getHeight(root.left)-getHeight(root.right)>1 || getHeight(root.right)-getHeight(root.left)>1){return false;}return isBalanced(root.left) && isBalanced(root.right);}
}

代码示例2:减少重复计算

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public int getHeight(TreeNode root){// 如果这棵树是一颗空树,自然就没有深度了if (root == null){return 0;}int leftHeight = getHeight(root.left);int rightHeight = getHeight(root.right);if(Math.abs(leftHeight-rightHeight)<=1 && leftHeight>=0 && rightHeight>=0){return Math.max(leftHeight,rightHeight)+1;}else{return -1;   // 当返回的是一个复数的时候,一定是不平衡}}public boolean isBalanced(TreeNode root) {// 如果是空树,就一定是一颗平衡树if(root == null){return true;}return getHeight(root) >= 0;}
}

5. 对称二叉树

101. 对称二叉树 - 力扣(LeetCode)

代码示例1:内存损耗比较多

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean isMirror(TreeNode p, TreeNode q) {// 如果一个为空,另一个不为空,则不对称if (p == null && q == null) {return true;}if (p == null || q == null) {return false;}// 递归判断对称性:左子树的左子树 vs 右子树的右子树,左子树的右子树 vs 右子树的左子树return (p.val == q.val) && isMirror(p.left, q.right) && isMirror(p.right, q.left);
}public boolean isSymmetric(TreeNode root) {if (root == null) {return true;}return isMirror(root.left, root.right);
}}

6. 二叉树的构建及遍历

二叉树遍历_牛客题霸_牛客网

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

import java.util.Scanner;// 定义一个节点
class TreeNode{char key;  // 因为是字符串类型的TreeNode left;TreeNode right;// 给一个不带参数的构造方法public TreeNode(){}// 给一个带参数的构造方法public TreeNode(char key){this.key = key;}
}// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString str = in.nextLine();TreeNode root = createTree(str);inorder(root);}}public static int i = 0;// 来一个创建二叉树的方法public static TreeNode createTree(String str){TreeNode root = null;if(str.charAt(i) != '#'){root = new TreeNode(str.charAt(i));i++;root.left = createTree(str);root.right = createTree(str);}else{i++;}return root;}// 中序遍历public static void inorder(TreeNode root){if(root == null){return;}inorder(root.left);System.out.print(root.key+" ");inorder(root.right);}}

7. 二叉树的分层遍历

102. 二叉树的层序遍历 - 力扣(LeetCode)

思路一:采用队列

思路如上图所示,我们是利用以一个队列来存储我们的中间数据

public void levelOrder(TreeNode root){// 如果根节点为空,则直接返回,什么都不输出if (root == null){return;}Queue<TreeNode> queue = new LinkedList<>();  // 创建一个队列来放元素的queue.offer(root);while (!queue.isEmpty()) {  // 只要队列不为空,就继续遍历TreeNode cur = queue.poll();  // 取出队首元素System.out.print(cur.val + " ");  // 访问该节点// 将左子节点加入队列if (cur.left != null) {queue.offer(cur.left);}// 将右子节点加入队列if (cur.right != null) {queue.offer(cur.right);}}}

思路2:使用顺序表

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {// 如果根节点为空,则直接返回,什么都不输出List<List<Integer>> list = new ArrayList<>();if (root == null){return list;}Queue<TreeNode> queue = new LinkedList<>();  // 创建一个队列来放元素的queue.offer(root);while (!queue.isEmpty()){// 求一下当前队列的大小int size = queue.size();List<Integer> tmp = new ArrayList<>();while (size!=0){TreeNode cur = queue.poll();tmp.add(cur.val);size--;if (cur.left != null){queue.offer(cur.left);}if (cur.right != null){queue.offer(cur.right);}}list.add(tmp);}return list;}
}

8. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

三种情况:

代码展示1:

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {/**先判断几种特殊情况*/if(root == null){return null;}if(p == root || q == root){return root;}/**如果上述几种情况都不满足的话*/TreeNode leftroot = lowestCommonAncestor(root.left,p,q);TreeNode rightroot = lowestCommonAncestor(root.right,p,q);if(leftroot!=null && rightroot!=null){// 说明分别在root左右两边找到了p,qreturn root;}else if(rightroot == null){// 说明在左边return leftroot;}else{return rightroot;}}
}

代码展示2:更简便【链表的相交节点】

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {Stack<TreeNode> stackP = new Stack<>();Stack<TreeNode> stackQ = new Stack<>();public boolean getPath(TreeNode root,TreeNode node,Stack<TreeNode> stack){if(root == null || node == null){return false;}stack.push(root);if(root == node){return true;}boolean flg1 = getPath(root.left,node,stack);if(flg1){return true;}boolean flg2 = getPath(root.right,node,stack);if(flg2){return true;}stack.pop();return false;}public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null){return null;}getPath(root,p,stackP);getPath(root,q,stackQ);int sizeP = stackP.size();int sizeQ = stackQ.size();if(sizeP > sizeQ){for(int i = 0;i<sizeP-sizeQ;i++){stackP.pop();}}if(sizeQ > sizeP){for(int i = 0;i<sizeQ-sizeP;i++){stackQ.pop();}}while(stackP!=null && stackQ!=null){TreeNode nodeP = stackP.pop();TreeNode nodeQ = stackQ.pop();if(nodeP == nodeQ){return nodeP;}}return null;}
}    

9. 根据一棵树的前序遍历与中序遍历构造二叉树。

105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}private TreeNode helper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {if (preStart > preEnd || inStart > inEnd) return null;int rootVal = preorder[preStart]; // 先序遍历的第一个值是根节点TreeNode root = new TreeNode(rootVal);// 在 inorder 里找到 rootVal 的索引int rootIndex = inStart;while (rootIndex <= inEnd && inorder[rootIndex] != rootVal) {rootIndex++;}int leftSize = rootIndex - inStart; // 左子树大小// 递归构造左子树root.left = helper(preorder, preStart + 1, preStart + leftSize, inorder, inStart, rootIndex - 1);// 递归构造右子树root.right = helper(preorder, preStart + leftSize + 1, preEnd, inorder, rootIndex + 1, inEnd);return root;}}

10. 根据一棵树的中序遍历与后序遍历构造二叉树

106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {return helper(inorder, 0, inorder.length - 1, postorder, 0, postorder.length - 1);}private TreeNode helper(int[] inorder, int inStart, int inEnd, int[] postorder, int postStart, int postEnd) {if (inStart > inEnd || postStart > postEnd) return null;int rootVal = postorder[postEnd]; // 后序遍历的最后一个值是根节点TreeNode root = new TreeNode(rootVal);// 在 inorder 里找到 rootVal 的索引int rootIndex = inStart;while (rootIndex <= inEnd && inorder[rootIndex] != rootVal) {rootIndex++;}int leftSize = rootIndex - inStart; // 左子树大小// 递归构造左子树root.left = helper(inorder, inStart, rootIndex - 1, postorder, postStart, postStart + leftSize - 1);// 递归构造右子树root.right = helper(inorder, rootIndex + 1, inEnd, postorder, postStart + leftSize, postEnd - 1);return root;}
}

11. 二叉树创建字符串

606. 根据二叉树创建字符串 - 力扣(LeetCode)

自己去AI,因为比较难;


12. 二叉树前序非递归遍历实现 

144. 二叉树的前序遍历 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null){return list;  //直接返回,有可能list也是一个空的}list.add(root.val);List<Integer> LeftTree = preorderTraversal(root.left);  // 处理左子树list.addAll(LeftTree);List<Integer> RightTree = preorderTraversal(root.right);  // 处理左子树list.addAll(RightTree);return list;}
}

13. 二叉树中序非递归遍历实现

94. 二叉树的中序遍历 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null){return list;  //直接返回,有可能list也是一个空的}List<Integer> LeftTree = inorderTraversal(root.left);  // 处理左子树list.addAll(LeftTree);list.add(root.val);List<Integer> RightTree = inorderTraversal(root.right);  // 处理左子树list.addAll(RightTree);return list;}
}

14. 二叉树后序非递归遍历实现

145. 二叉树的后序遍历 - 力扣(LeetCode)

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> list = new ArrayList<>();if(root == null){return list;  //直接返回,有可能list也是一个空的}List<Integer> LeftTree = postorderTraversal(root.left);  // 处理左子树list.addAll(LeftTree);List<Integer> RightTree = postorderTraversal(root.right);  // 处理左子树list.addAll(RightTree);list.add(root.val);return list;}
}

15.怎么判断一棵树是不是完全二叉树

如上图所示,当第一个null后面不全是null,说明这不是一个完全二叉树。如果第一个空后面全是空,则为一个完全二叉树。

/*** 判断一棵树是不是完全二叉树* @param root* @return*/public boolean isCompleteTree(TreeNode root){// 如果根节点为空,则直接返回,什么都不输出if (root == null){return true;}Queue<TreeNode> queue = new LinkedList<>();  // 创建一个队列来放元素的queue.offer(root);while (!queue.isEmpty()) {  // 只要队列不为空,就继续遍历TreeNode cur = queue.poll();  // 取出队首元素if (cur != null){queue.offer(cur.left);queue.offer(cur.right);}else {break;  // 退出该循环【也是说明碰到了一个null】}}while (!queue.isEmpty()){if (queue.poll() != null){return false;}}return true;}

16.前序遍历的非递归实现

/*** 非递归的前序遍历*/public void preOrder3(TreeNode root){// 如果根节点为空if(root == null){return;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;TreeNode top = null;while (cur != null || stack.isEmpty()){while (cur != null){stack.push(cur);System.out.print(cur.val + " ");cur = cur.left;}top = stack.pop();cur = top.right;}}

上述代码是用来实现的

小编写到这里,发现很多代码的实现都是用了一个栈或者两个栈结合一个变量【该变量用来存储从栈顶弹出的元素来改变引用的指向


17.中序遍历的非递归实现

/*** 中序遍历的非递归实现*/public void inOrder2(TreeNode root) {if (root == null){return;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;TreeNode top = null;while (cur!=null||!stack.isEmpty()){while (cur != null){stack.push(cur);cur = cur.left;}top = stack.pop();System.out.print(top.val + " ");cur = top.right;}}

18.后续遍历的二叉树实现

/*** 后序遍历的非递归实现*/void postOrder2(TreeNode root){if (root == null){return;}Stack<TreeNode> stack = new Stack<>();TreeNode cur = root;TreeNode top = null;TreeNode prev = null;while (cur!=null||!stack.isEmpty()){while (cur != null){stack.push(cur);cur = cur.left;}top = stack.peek();if (top.right == null || top.right == prev){stack.pop();System.out.print(top.val + " ");prev = top; // 当前这个节点被打印了}else {cur = top.right;}}

http://www.dtcms.com/wzjs/268110.html

相关文章:

  • 哪个公司做农村产权交易网站百度竞价推广计划
  • 人们做网站怎么赚钱哪里做网络推广
  • 怎么从网站上看出做网站的日期google store
  • 网站推广有必要吗模板建站难吗
  • 学校网站建设意义有哪些网站开发平台有哪些
  • 自己可以给公司做网站吗视频号广告推广
  • 电子商务网站设计代码seo内部优化方式包括
  • 嘉善县科正建设网站外链网站大全
  • 怎样免费建立网站网站关键词在线优化
  • 重庆有多少网站百度推广费用怎么算
  • 网站二维码弹窗最近国家新闻
  • 手机能访问asp网站淘宝自动推广软件
  • 有趣的网络营销案例重庆seo推广外包
  • 网站开发模板带css样式惠州百度推广排名
  • 怎么在网站添加链接在线网站建设平台
  • 建设公司网站需要多少天seo搜索引擎优化教程
  • 沧州网站域名注册服务公司深圳seo关键词优化
  • 佛山全网营销型网站建设网站开发公司排名
  • 芜湖做网站哪个公司好百度推广点击一次多少钱
  • 判断网站cms希爱力双效片的作用与功效
  • 合肥网络运营公司哪家好某个网站seo分析实例
  • wordpress博客文章美化厦门百度快照优化排名
  • wordpress子主题下载西安seo优化排名
  • 网站模板免费下载酒店管理系统国家认可的教育培训机构
  • ps做 网站教程网络工程师培训机构排名
  • 网站服务器租用一年多少钱啊西安seo网络优化公司
  • 禅城网站建设seo标题优化是什么意思
  • 校园网站建设的系统分析小说网站排名人气
  • 合肥做网站推广seo搜索优化排名
  • 网页设计师培训需要多少钱杭州百度百家号seo优化排名