二叉树的先序遍历、中序遍历、后序遍历、层次遍历
介绍二叉树的4中遍历方式
java用递归和非递归方式实现前序中序后序遍历
二叉树的遍历方式,
1. 先序遍历 Pre-order
前序遍历:
若二叉树为空,则空操作返回,
否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。
特点:1. 根----->左----->右 2. 根据前序遍历的结果可知第一个访问的必定是root结点。
2. 中序遍历 Inorder Traversal(LDR)
中序遍历:
若二叉树为空,则空操作返回,
否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后访问根结点,最后中序遍历右子树。
特点:1. 左----->根------->右 2. 根据中序遍历的结果,再结合前序遍历的root结点去划分root结点的左右子树。
3. 后序遍历 Postorder Traversal(LRD)
后序遍历:
若二叉树为空,则空操作返回,
否则从左到右先叶子结点后结点的方式遍历访问左右子树,最后访问根结点。
特点:1. 左------>右------>根 2. 根据后序遍历的结果可知最后访问的必定是root结点。
4. 层序遍历
层序遍历:
若二叉树为空,则空返回,
否则从树的第一层,即根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。
特点:1. 从左到右,从上到下 2. 可知第一个访问的必定是root结点
java递归非递归 实现前序中序后序遍历二叉树
package cn.altman.common.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* Created by xuzhihua on 1/5/2018.
*/
class TreeNode<T> {
private T value;
private TreeNode<T> left;
private TreeNode<T> right;
public T getValue() {return value;}
public void setValue(T value) {this.value = value;}
public TreeNode<T> getLeft() {return left;}
public void setLeft(TreeNode<T> left) {this.left = left;}
public TreeNode<T> getRight() {return right;}
public void setRight(TreeNode<T> right) {this.right = right;}
}
// 前序遍历 Preorder Traversal (DLR)
class PreOrder<T> {
// 递归
public List<T> travelWithRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
doTravelRecursion(tree, result);
return result;
}
private void doTravelRecursion(TreeNode<T> tree, List<T> result) {
if (tree == null)
return;
result.add(tree.getValue());
if (tree.getLeft() != null)
doTravelRecursion(tree.getLeft(), result);
if (tree.getRight() != null)
doTravelRecursion(tree.getRight(), result);
}
// 非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
stack.push(tree);
while (!stack.empty()) {
TreeNode<T> node = stack.pop();
result.add(node.getValue());
if (node.getRight() != null) {
stack.push(node.getRight());
}
if (node.getLeft() != null) {
stack.push(node.getLeft());
}
}
return result;
}
}
// 中序遍历 Inorder Traversal (LDR)
class InOrder<T> {
// 递归
public List<T> travelWithRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
doTravelRecursion(tree, result);
return result;
}
private void doTravelRecursion(TreeNode<T> tree, List<T> result) {
if (tree == null)
return;
if (tree.getLeft() != null)
doTravelRecursion(tree.getLeft(), result);
result.add(tree.getValue());
if (tree.getRight() != null)
doTravelRecursion(tree.getRight(), result);
}
// 非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
TreeNode<T> node = tree;
while (!stack.empty() || node != null) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
if (!stack.empty()) {
node = stack.pop();
result.add(node.getValue());
node = node.getRight();
}
}
return result;
}
}
// 后序遍历 Postorder Traversal (LRD)
class PostOrder<T> {
// 递归
public List<T> travelWithRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
doTravelRecursion(tree, result);
return result;
}
private void doTravelRecursion(TreeNode<T> tree, List<T> result) {
if (tree == null)
return;
if (tree.getLeft() != null)
doTravelRecursion(tree.getLeft(), result);
if (tree.getRight() != null)
doTravelRecursion(tree.getRight(), result);
result.add(tree.getValue());
}
// 非递归
public List<T> travelWithoutRecursion(TreeNode<T> tree) {
List<T> result = new ArrayList<T>();
Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();
TreeNode<T> currentNode = tree;
TreeNode<T> lastNode = null;
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.getLeft();
}
while (!stack.empty()) {
currentNode = stack.pop();
//只有“当前节点”没有右孩子或者右孩子已经被访问过了,才可以访问“当前节点”
if (currentNode.getRight() == null || currentNode.getRight() == lastNode) {
result.add(currentNode.getValue());
lastNode = currentNode;
}
else {
stack.push(currentNode);
currentNode = currentNode.getRight();
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.getLeft();
}
}
}
return result;
}
}
public class TraversalOfBinaryTreeDemo {
public static void main(String[] args) {
// 初始化 二叉树 数据
TreeNode<String> root = prepareData();
PreOrder<String> preOrder = new PreOrder<String>();
InOrder<String> inOrder = new InOrder<String>();
PostOrder<String> postOrder = new PostOrder<String>();
System.out.println("先序遍历 非递归\t\t" + String.join(", ", preOrder.travelWithoutRecursion(root)));
System.out.println("先序遍历 递归\t\t" + String.join(", ", preOrder.travelWithRecursion(root)));
System.out.println();
System.out.println("中序遍历 非递归\t\t" + String.join(", ", inOrder.travelWithoutRecursion(root)));
System.out.println("中序遍历 递归\t\t" + String.join(", ", inOrder.travelWithRecursion(root)));
System.out.println();
System.out.println("后序遍历 非递归\t\t" + String.join(", ", postOrder.travelWithoutRecursion(root)));
System.out.println("后序遍历 递归\t\t" + String.join(", ", postOrder.travelWithRecursion(root)));
System.out.println();
}
/**
* 1
* 2 3
* 4 5 6 7
* 8 9
* 初始化节点数据
*/
private static TreeNode<String> prepareData() {
TreeNode<String> root = new TreeNode<String>();
root.setValue("1");
TreeNode<String> node1 = new TreeNode<String>();
node1.setValue("2");
root.setLeft(node1);
TreeNode<String> node1_1 = new TreeNode<String>();
node1_1.setValue("4");
node1.setLeft(node1_1);
TreeNode<String> node1_2 = new TreeNode<String>();
node1_2.setValue("5");
node1.setRight(node1_2);
TreeNode<String> node8 = new TreeNode<String>();
node8.setValue("8");
node1_1.setLeft(node8);
TreeNode<String> node9 = new TreeNode<String>();
node9.setValue("9");
node1_1.setRight(node9);
TreeNode<String> node2 = new TreeNode<String>();
node2.setValue("3");
root.setRight(node2);
TreeNode<String> node2_1 = new TreeNode<String>();
node2_1.setValue("6");
node2.setLeft(node2_1);
TreeNode<String> node2_2 = new TreeNode<String>();
node2_2.setValue("7");
node2.setRight(node2_2);
return root;
}
}
/**
*输出结果
先序遍历 非递归 1, 2, 4, 8, 9, 5, 3, 6, 7
先序遍历 递归 1, 2, 4, 8, 9, 5, 3, 6, 7
中序遍历 非递归 8, 4, 9, 2, 5, 1, 6, 3, 7
中序遍历 递归 8, 4, 9, 2, 5, 1, 6, 3, 7
后序遍历 非递归 8, 9, 4, 5, 2, 6, 7, 3, 1
后序遍历 递归 8, 9, 4, 5, 2, 6, 7, 3, 1
*/