前言
- 今天在力扣上看到这样一道题,感觉挺有趣,而后几经挫折解出来,结果和其他博主的有异同~
题目
- 给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。
例如:给定二叉树: [3,9,20,null,null,15,7]
- 输出
- 摘自力扣102题
解题思路/知识点
- 层级遍历二叉树,一般借助队列作为缓冲。
- 头节点出队列,同时判断头节点是否含有左右子节点,如果有,则入队列。
- 如何判断层级?
本篇借助在队列里插入【干扰因子】的方式,即一个标识符来判断层级。 - 以此树来演示
- 步骤:null入队–>头节点入队(3)–>null出队->null入队尾->头节点出队(3)->头节点的左右节点入队(9/20)->null出队->null入队尾->9出队->20出队;
- 以上方法表示两个null之间是一个层级,如果还有模糊,不急,showCode。
showCode
- 万物皆对象~
创建节点对象
public class TreeNode {
int value;
TreeNode lNode;
TreeNode rNode;
//设置value值
public void setValue(int value) {
this.value = value;
}
//设置左节点
public void setlNode(TreeNode lNode){
this.lNode = lNode;
}
//设置右节点
public void setrNode(TreeNode rNode){
this.rNode = rNode;
}
//前序遍历
public void frontShow() {
//先遍历当前节点的内容
System.out.println(value);
//遍历左节点
if(lNode!=null){
lNode.frontShow();
}
//遍历右节点
if(rNode!=null){
rNode.frontShow();
}
}
}
创建树对象
public class BinaryTree {
TreeNode root;
//设置根节点
public void setRoot(TreeNode root) {
this.root = root;
}
//前序遍历
public void frontShow(){
this.root.frontShow();
}
}
创建测试类
public class Solution {
//用于创建二叉树节点集合
List<TreeNode> treeNodes = new ArrayList<TreeNode>();
//二叉树
BinaryTree tree = new BinaryTree();
public static void main(String[] args) {
}
}
- 首先编写一个创建二叉树的方法,我们使用递归。
/**
* @param index 当前索引
* @param node 当前节点
* */
public void createBinaryTree(int index,TreeNode node) {
if(index == 0) {
tree.setRoot(treeNodes.get(index));
}
if(2*index+1<treeNodes.size() && node != null) {
node.setlNode(treeNodes.get(2*index+1));
createBinaryTree(2*index+1,node.lNode);
}
if(2*index+2<treeNodes.size() && node != null) {
node.setrNode(treeNodes.get(2*index+2));
createBinaryTree(2*index+2,node.rNode);
}
}
- 编写前序遍历方法(直接调用节点类方法)测试树是否可以正常创建
public static void main(String[] args) {
//前序数组
int[] testTree = {3,9,20,0,0,15,7};
Solution testSolution = new Solution();
//创建节点集合
testSolution.createNodes(testTree);
TreeNode root = new TreeNode();
root.value = 3;
//创建二叉树
testSolution.createBinaryTree(0, root);
testSolution.setRoot(root);
//前序遍历
testSolution.fontShow();
}
- 前序遍历结果
- 此过程设计顺序存储二叉树的知识,将数组—>二叉树
层序遍历
//按照层级遍历二叉树
public void traversal(){
//使用到的工具集合---队列
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//定义结果集
List<List<Integer>> result = new ArrayList<List<Integer>>();
//结果集中的List
List<Integer> res = null;
queue.add(null);
queue.add(testSolution.tree.root);
int level = -1;
while(!queue.isEmpty()) {
TreeNode temp=queue.poll();
//判断层级/防止进入恶性循环
if(temp == null) {
level++;
res = new ArrayList<Integer>();
result.add(res);
queue.add(null);
}
//防止空指针
if(res != null && temp != null) {
result.get(level).add(temp.value);
}
if(temp != null && temp.lNode != null && temp.lNode.value != 0) {
queue.add(temp.lNode);
}
if(temp != null && temp.rNode != null && temp.rNode.value != 0) {
queue.add(temp.rNode);
}
if(queue.peek() == null && queue.size()==1) {
break;
}
}
System.out.println("--------------------------------");
System.out.println(result);
}
- 上述代码大概是这样一个过程。图
-结果输出
锯齿遍历
题目
-给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
[ [3], [20,9], [15,7] ]
解体思路
- 有了上面的层序遍历,此题目算是上面的变体,我们只需把层级为偶数的节点值反转以下便可。
//判断层级+1
if(level!= - 1 && (level+1) % 2 == 0) {
Collections.reverse(result.get(level));
}
- 上述代码大概是这个酱紫
- 输出结果
源码(测试类)
public class Solution {
List<TreeNode> treeNodes = new ArrayList<TreeNode>();
BinaryTree tree = new BinaryTree();
public static void main(String[] args) {
//前序数组
int[] testTree = {3,9,20,0,0,15,7};
Solution testSolution = new Solution();
testSolution.createNodes(testTree);
TreeNode root = new TreeNode();
root.value = 3;
testSolution.createBinaryTree(0, root);
testSolution.setRoot(root);
//前序遍历
testSolution.fontShow();
//按照层级遍历二叉树
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//定义结果集
List<List<Integer>> result = new ArrayList<List<Integer>>();
//结果集中的List
List<Integer> res = null;
queue.add(null);
queue.add(testSolution.tree.root);
int level = -1;
while(!queue.isEmpty()) {
TreeNode temp=queue.poll();
//判断层级/防止进入恶性循环
if(temp == null) {
//判断层级+1
//如果是层级,去掉这个if
if(level!= - 1 && (level+1) % 2 == 0) {
Collections.reverse(result.get(level));
}
level++;
res = new ArrayList<Integer>();
result.add(res);
queue.add(null);
}
//防止空指针
if(res != null && temp != null) {
result.get(level).add(temp.value);
}
if(temp != null && temp.lNode != null && temp.lNode.value != 0) {
queue.add(temp.lNode);
}
if(temp != null && temp.rNode != null && temp.rNode.value != 0) {
queue.add(temp.rNode);
}
if(queue.peek() == null && queue.size()==1) {
break;
}
}
System.out.println(level);
System.out.println("--------------------------------");
System.out.println(result);
}
//创建节点对象集合,使用ArrayList存
public void createNodes(int[] tree) {
for(int i=0;i<tree.length;i++) {
TreeNode node = new TreeNode();
node.value = tree[i];
treeNodes.add(node);
}
}
//创建二叉树(递归)
/**
* @param index 当前索引
* @param node 当前节点
* */
public void createBinaryTree(int index,TreeNode node) {
if(index == 0) {
tree.setRoot(treeNodes.get(index));
}
if(2*index+1<treeNodes.size() && node != null) {
node.setlNode(treeNodes.get(2*index+1));
createBinaryTree(2*index+1,node.lNode);
}
if(2*index+2<treeNodes.size() && node != null) {
node.setrNode(treeNodes.get(2*index+2));
createBinaryTree(2*index+2,node.rNode);
}
}
//前序遍历
public void fontShow() {
tree.frontShow();
}
//设置根节点对象
public void setRoot(TreeNode node) {
tree.setRoot(node);
}
}
结语
如有错误,欢迎指正~