二叉树的遍历
1.前序遍历
根左右
非递归法
箭头序号对应访问步骤
打印结果:A B D E C F
/**
* 前序遍历 - 递归
* @param treeNode
*/
public static void rePreOrderTraversal(TreeNode treeNode) {
System.out.print(treeNode.value + "\t");
if(treeNode.letf != null) {
rePreOrderTraversal(treeNode.letf);
}
if(treeNode.right != null) {
rePreOrderTraversal(treeNode.right);
}
}
/**
* 前序遍历 - 非递归 - 栈
* @param treeNode
*/
public static void preOrderTraversal(TreeNode treeNode) {
// 利用栈存储路径 便于寻找双亲节点
Stack<TreeNode> stack = new Stack<>();
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
System.out.print(treeNode.value + "\t");
stack.push(treeNode);
treeNode = treeNode.letf;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
treeNode = treeNode.right;
}
}
}
2.中序遍历
左根右
非递归法
打印结果:D B E A C F
/**
* 中序遍历 - 递归
* @param treeNode
*/
public static void reInOrderTraversal(TreeNode treeNode) {
if (treeNode.letf != null) {
reInOrderTraversal(treeNode.letf);
}
System.out.print(treeNode.value + "\t");
if (treeNode.right != null) {
reInOrderTraversal(treeNode.right);
}
}
/**
* 中序遍历 - 非递归 - 栈
* @param treeNode
*/
public static void inOrderTraversal(TreeNode treeNode) {
Stack<TreeNode> stack = new Stack<>();
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
stack.push(treeNode);
treeNode = treeNode.letf;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
System.out.print(treeNode.value + "\t");
treeNode = treeNode.right;
}
}
}
3.后序遍历
左右根
非递归法-双栈法
后序遍历的方式是“左右根”如果我们可以做到“根右左”再逆序(栈)打印即可
类比前序的“根左右”
打印结果:D E B F C A
/**
* 后序遍历 - 递归
* @param treeNode
*/
public static void rePostOrderTraversal(TreeNode treeNode) {
if (treeNode.letf != null) {
rePostOrderTraversal(treeNode.letf);
}
if (treeNode.right != null) {
rePostOrderTraversal(treeNode.right);
}
System.out.print(treeNode.value + "\t");
}
/**
* 后序遍历 - 非递归 - 双栈
* @param treeNode
*/
public static void postOrderTraversal(TreeNode treeNode) {
Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> res = new Stack<>();// 存放"根右左"的遍历结果栈
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
stack.push(treeNode);
res.push(treeNode);
treeNode = treeNode.right;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
treeNode = treeNode.letf;
}
}
while (!res.isEmpty()) {
System.out.print(res.pop().value + "\t");
}
}
总结:
非递归法的遍历仅仅在打印(访问)根节点阶段略有不同
前序:入栈即打印
中序:出栈才打印
后序:入栈也入逆序栈
4.层序遍历(层次遍历)
利用队列
(1)将根节点入队;
(2)访问队首,如果队首有左右孩子,就依次将左右孩子入队,队首出队(打印);
(3)循环(2)直到队空;
/**
* 层次遍历 - 队列
* @param treeNode
*/
public static void levelOrderTraversal(TreeNode treeNode) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(treeNode);
while (!queue.isEmpty()) {
TreeNode head = queue.poll();// 获取队首元素
if (head.letf != null) {
queue.offer(head.letf);
}
if (head.right != null) {
queue.offer(head.right);
}
System.out.print(head.value + "\t");
}
System.out.println();
}
代码汇总
package com.tree;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* @program: DataStructures
* @description: 二叉树
* @author: XuDeming
* @date: 2020-01-02 10:17:01
**/
public class BinaryTreeTraversalDemo {
public static void main(String[] args) {
TreeNode root = 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");
root.letf = node2;
root.right = node3;
node2.letf = node4;
node2.right = node5;
node3.right = node6;
System.out.println("递归方式");
if (root != null) {
rePreOrderTraversal(root);
System.out.println();
reInOrderTraversal(root);
System.out.println();
rePostOrderTraversal(root);
System.out.println();
}
System.out.println("----------------------");
System.out.println("非递归方式");
preOrderTraversal(root);
System.out.println();
inOrderTraversal(root);
System.out.println();
postOrderTraversal(root);
System.out.println();
System.out.println("----------------------");
System.out.println("层次遍历");
levelOrderTraversal(root);
}
/**
* 前序遍历 - 递归
* @param treeNode
*/
public static void rePreOrderTraversal(TreeNode treeNode) {
System.out.print(treeNode.value + "\t");
if(treeNode.letf != null) {
rePreOrderTraversal(treeNode.letf);
}
if(treeNode.right != null) {
rePreOrderTraversal(treeNode.right);
}
}
/**
* 前序遍历 - 非递归 - 栈
* @param treeNode
*/
public static void preOrderTraversal(TreeNode treeNode) {
// 利用栈存储路径 便于寻找双亲节点
Stack<TreeNode> stack = new Stack<>();
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
System.out.print(treeNode.value + "\t");
stack.push(treeNode);
treeNode = treeNode.letf;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
treeNode = treeNode.right;
}
}
}
/**
* 中序遍历 - 递归
* @param treeNode
*/
public static void reInOrderTraversal(TreeNode treeNode) {
if (treeNode.letf != null) {
reInOrderTraversal(treeNode.letf);
}
System.out.print(treeNode.value + "\t");
if (treeNode.right != null) {
reInOrderTraversal(treeNode.right);
}
}
/**
* 中序遍历 - 非递归 - 栈
* @param treeNode
*/
public static void inOrderTraversal(TreeNode treeNode) {
Stack<TreeNode> stack = new Stack<>();
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
stack.push(treeNode);
treeNode = treeNode.letf;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
System.out.print(treeNode.value + "\t");
treeNode = treeNode.right;
}
}
}
/**
* 后序遍历 - 递归
* @param treeNode
*/
public static void rePostOrderTraversal(TreeNode treeNode) {
if (treeNode.letf != null) {
rePostOrderTraversal(treeNode.letf);
}
if (treeNode.right != null) {
rePostOrderTraversal(treeNode.right);
}
System.out.print(treeNode.value + "\t");
}
/**
* 后序遍历 - 非递归 - 双栈
* @param treeNode
*/
public static void postOrderTraversal(TreeNode treeNode) {
Stack<TreeNode> stack = new Stack<>();
Stack<TreeNode> res = new Stack<>();// 存放"根右左"的遍历结果栈
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
stack.push(treeNode);
res.push(treeNode);
treeNode = treeNode.right;
}
if (!stack.isEmpty()) {
treeNode = stack.pop();
treeNode = treeNode.letf;
}
}
while (!res.isEmpty()) {
System.out.print(res.pop().value + "\t");
}
}
/**
* 层次遍历 - 队列
* @param treeNode
*/
public static void levelOrderTraversal(TreeNode treeNode) {
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(treeNode);
while (!queue.isEmpty()) {
TreeNode head = queue.poll();// 获取队首元素
if (head.letf != null) {
queue.offer(head.letf);
}
if (head.right != null) {
queue.offer(head.right);
}
System.out.print(head.value + "\t");
}
System.out.println();
}
}
// 节点
class TreeNode {
String value;
TreeNode letf;
TreeNode right;
public TreeNode(String value) {
this.value = value;
}
}