一、层序遍历的概念
将一颗二叉树按照层次顺序遍历整棵树。先遍历第一层(root层),接着遍历第二层,再接着时第三层…直到将所有节点遍历完成。
层序遍历示意图
二、思路分析
完成层序遍历需要用到一个队列Queue来辅助。
1、若当前节点不为空,将当前节点入队列;
2、判断当前队列是否为空;
3、若队列不为空,第一个元素出队列,并将其左子树入队列、右子树入队列;
4、若队列为空,说明层序遍历完成;
三、代码
package com.tree;
import java.util.LinkedList;
public class BinaryTreeTest {
public static void main(String[] args) {
TreeNode node1 = new TreeNode(1, "李白");
TreeNode node2 = new TreeNode(2, "宫本");
TreeNode node3 = new TreeNode(3, "韩信");
TreeNode node4 = new TreeNode(4, "甄姬");
TreeNode node5 = new TreeNode(5, "鲁班");
TreeNode node6 = new TreeNode(6, "孙尚香");
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.right = node6;
BinaryTree binaryTree = new BinaryTree(node1);
binaryTree.levelOrder();
System.out.println(binaryTree.getHeight());
}
}
class BinaryTree {
public TreeNode root;
public BinaryTree(TreeNode root) {
this.root = root;
}
/**
* 前序遍历
*/
public void preOrder() {
if (root != null) {
root.preOrder();
} else {
System.out.println("树为空!");
}
}
/**
* 中序遍历
*/
public void infixOrder() {
if (root != null) {
root.infixOrder();
} else {
System.out.println("树为空!");
}
}
/**
* 后序遍历
*/
public void postOrder() {
if (root != null) {
root.postOrder();
} else {
System.out.println("树为空!");
}
}
/**
* 层序遍历思路: 1、需要一个辅助队列 2、若当前节点不为空,则将当前节点入队列 3、若当前节点的左子树不为空,则左子树入队列
* 4、若当前节点的右子树不为空,则右子树入队列 5、判断队列是否为空 6、若队列不为空,第一个出队列,并将其左右子树入队列
*/
public void levelOrder() {
if (root != null) {
root.levelOrder();
} else {
System.out.println("树为空!");
}
}
public int getHeight() {
if (root != null) {
return root.getHeight();
} else {
return 0;
}
}
}
class TreeNode {
int id; // id
String name; // 姓名
TreeNode left; // 左子树
TreeNode right; // 右子树
public TreeNode(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "TreeNode [id=" + id + ", name=" + name + "]";
}
/**
* 前序遍历
*
* @param node
*/
public void preOrder() {
// 先输出当前节点
System.out.println(this);
// 左子树不为空,遍历左子树
if (this.left != null) {
this.left.preOrder();
}
// 右子树不为空,遍历右子树
if (this.right != null) {
this.right.preOrder();
}
}
/**
* 中序遍历
*
* @param node
*/
public void infixOrder() {
// 先遍历左子树
if (this.left != null) {
this.left.infixOrder();
}
// 输出当前节点
System.out.println(this);
// 遍历右子树
if (this.right != null) {
this.right.infixOrder();
}
}
/**
* 后序遍历
*
* @param node
*/
public void postOrder() {
// 先遍历左子树
if (this.left != null) {
this.left.postOrder();
}
// 遍历左子树
if (this.right != null) {
this.right.postOrder();
}
// 输出当前节点
System.out.println(this);
}
/**
* 层序遍历
*/
public void levelOrder() {
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
// 先将当前节点入队列
if(this!=null) {
queue.add(this);
}
while (true) {
// 当队列为空的时候说面遍历完成
if (queue.isEmpty()) {
break;
} else {
// 出队列一个
TreeNode temp = queue.poll();
System.out.println(temp);
if (temp.left != null) {
queue.add(temp.left);
}
if (temp.right != null) {
queue.add(temp.right);
}
}
}
}
/**
* @return 树的高度
*/
public int getHeight() {
int height = 0;
int heightLeft = 0;
int heightRight = 0;
// 当前节点不为空,就将当前节点为根的树的高度+1
if (this != null) {
// 以当前节点为根的树的高度+1
height += 1;
// 计算左子树的高度
if (this.left != null) {
heightLeft += this.left.getHeight();
}
// 计算右子树的高度
if (this.right != null) {
heightRight += this.right.getHeight();
}
// 以树的高度=max(左子树高度,右子树高度)
height += Math.max(heightLeft, heightRight);
}
return height;
}
}