编程题-算法-中等-牛客网-NC15 求二叉树的层序遍历
1、题目:NC15 求二叉树的层序遍历
2、编程解答
2.1 方法一:递归方法
第一种方法:递归方法,使用二叉树的前序遍历递归方式,再利用一个变量记录当前递归的深度,然后进行层序的遍历的记录。
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
ArrayList<ArrayList<Integer>> resList = new ArrayList<>();
levelSearch(root, resList, 1);
return resList;
}
public static void levelSearch(TreeNode root, ArrayList<ArrayList<Integer>> resList, int level) {
// 递归条件
if (root==null) {
return;
}
if (resList.size()<level) {
// 如果返回数组的长度小于递归的深度,说明访问的是level层的第一个元素,需要将返回数组容量+1
ArrayList<Integer> list = new ArrayList<>();
list.add(root.val);
resList.add(list);
} else {
// 否则就将当前元素的值放入待返回数组中
resList.get(level-1).add(root.val);
}
// 然后递归该方法
levelSearch(root.left, resList, level+1);
levelSearch(root.right, resList, level+1);
}
}
通过的截图如下:
2.2 方法二:非递归方法——广度优先遍历法
第二种方法:非递归方法,利用一个队列进行广度优先遍历。
广度有限遍历的步骤如下:
1:头节点进入队列
2:当队列不为空时,记录下此时队列总数queueNum,然后for循环queueNum次:
2.1 队首元素出队列
2.2 打印该节点
2.3 该节点的所有非叶子节点进入队列
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
// 利用一个队列进行广度优先遍历。
// 广度有限遍历的步骤如下:
// 1:头节点进入队列
// 2:当队列不为空时,记录下此时队列总数queueNum,for循环queueNum次:
// 2.1 队首元素出队列
// 2.2 打印该节点
// 2.3 该节点的所有非叶子节点进入队列
ArrayList<ArrayList<Integer>> resList = new ArrayList<>();
ArrayList<TreeNode> queueList = new ArrayList<>();
if (root!=null) {
// 头节点不为空的话,头节点进入队列
queueList.add(root);
}
while (queueList.size()>0) {
ArrayList<Integer> resListUnit = new ArrayList<>();
int queueNum = queueList.size();
for (int i=0; i<queueNum; i++) {
// for循环queueNum次,也就是将这一层的所有元素都遍历一遍
TreeNode treeNode = queueList.get(0);
queueList.remove(0);
if (treeNode!=null) {
resListUnit.add(treeNode.val);
if (treeNode.left!=null) {
queueList.add(treeNode.left);
}
if (treeNode.right!=null) {
queueList.add(treeNode.right);
}
}
}
resList.add(resListUnit);
}
return resList;
}
}
通过的截图如下:
3、两种方法的自测代码
两种方法的自测代码如下:
package com.koping.test;
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class test006 {
public static void main(String[] args) {
TreeNode Node11 = new TreeNode();
Node11.val = 1;
TreeNode Node21 = new TreeNode();
Node21.val = 2;
TreeNode Node22 = new TreeNode();
Node22.val = 3;
Node11.left = Node21;
Node11.right = Node22;
TreeNode Node31 = new TreeNode();
Node31.val = 4;
TreeNode Node32 = new TreeNode();
Node32.val = 5;
Node21.right = Node32;
TreeNode Node33 = new TreeNode();
Node33.val = 6;
TreeNode Node34 = new TreeNode();
Node34.val = 7;
Node22.left = Node33;
Node22.right = Node34;
System.out.println("方法一:使用递归方法:");
ArrayList<ArrayList<Integer>> res = levelOrder1(Node11);
System.out.println(res);
System.out.println("方法二:使用非递归方法:广度优先遍历法(Breadth-First-Search)");
ArrayList<ArrayList<Integer>> res2 = levelOrder2(Node11);
System.out.println(res2);
}
public static ArrayList<ArrayList<Integer>> levelOrder1(TreeNode root) {
// 递归方法,利用一个变量记录当前递归的深度。
ArrayList<ArrayList<Integer>> resList = new ArrayList<>();
levelSearch(root, resList, 1);
return resList;
}
public static void levelSearch(TreeNode root, ArrayList<ArrayList<Integer>> resList, int level) {
// 递归条件
if (root==null) {
return;
}
if (resList.size()<level) {
// 如果返回数组的长度小于递归的深度,说明访问的是level层的第一个元素,需要将返回数组容量+1
ArrayList<Integer> list = new ArrayList<>();
list.add(root.val);
resList.add(list);
} else {
// 否则就将当前元素的值放入待返回数组中
resList.get(level-1).add(root.val);
}
// 然后递归该方法
levelSearch(root.left, resList, level+1);
levelSearch(root.right, resList, level+1);
}
public static ArrayList<ArrayList<Integer>> levelOrder2(TreeNode root) {
// 利用一个队列进行广度优先遍历。
// 广度有限遍历的步骤如下:
// 1:头节点进入队列
// 2:当队列不为空时,记录下此时队列总数queueNum,for循环queueNum次:
// 2.1 队首元素出队列
// 2.2 打印该节点
// 2.3 该节点的所有非叶子节点进入队列
ArrayList<ArrayList<Integer>> resList = new ArrayList<>();
ArrayList<TreeNode> queueList = new ArrayList<>();
if (root!=null) {
// 头节点不为空的话,头节点进入队列
queueList.add(root);
}
while (queueList.size()>0) {
ArrayList<Integer> resListUnit = new ArrayList<>();
int queueNum = queueList.size();
for (int i=0; i<queueNum; i++) {
// for循环queueNum次,也就是将这一层的所有元素都遍历一遍
TreeNode treeNode = queueList.get(0);
queueList.remove(0);
if (treeNode!=null) {
resListUnit.add(treeNode.val);
if (treeNode.left!=null) {
queueList.add(treeNode.left);
}
if (treeNode.right!=null) {
queueList.add(treeNode.right);
}
}
}
resList.add(resListUnit);
}
return resList;
}
}
运行结果如下:
/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea/idea-IC-203.8084.24/lib/idea_rt.jar=46861:/opt/idea/idea-IC-203.8084.24/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/java/tmp/test/out/production/test com.koping.test.test006
方法一:使用递归方法:
[[1], [2, 3], [5, 6, 7]]
方法二:使用非递归方法:广度优先遍历法(Breadth-First-Search)
[[1], [2, 3], [5, 6, 7]]
Process finished with exit code 0