二叉树遍历即将二叉树中所有的节点遍历一遍,根据节点遍历的顺序的不同,分为前序遍历,中序遍历。下面这个图为要遍历的二叉树(图来自参考文献2)。
每种遍历方式中,包含两种,递归方法和非递归方法。
遍历的主要流程:
前序遍历思路:
/**
* 前序遍历,递归方法.
* @param root 根节点
*/
public void preOrder(Node root){
if (root!=null){
printNode(root); //访问根节点
preOrder(root.getLeftNode()); //前序遍历左子树
preOrder(root.getRightNode()); //前序遍历右子树
}
}
/**
* 前序遍历,非递归方法.
* @param root 根节点
*/
public void preOrder_stack(Node root){
Stack stack = new Stack<>();
while(root!=null || !stack.isEmpty()){
if(root!=null){
printNode(root); //访问根节点
stack.push(root); //入栈
root = root.getLeftNode(); //访问左子树
}else{
root = stack.pop(); //回溯至父节点
root = root.getRightNode(); //访问右子树
}
}
System.out.println();
}
输出结果为:
前序遍历
6 3 1 2 5 4 9 7 8
中序遍历思路:
/**
* 中序遍历,递归方式.
* @param root 根节点
*/
public void inOrder(Node root){
if (root!=null){
inOrder(root.getLeftNode()); //中序遍历左子树
printNode(root); //访问根节点
inOrder(root.getRightNode()); //中序遍历右子树
}
}
/**
* 中序遍历,非递归方式.
* @param root 根节点
*/
public void inOrder_stack(Node root){
Stack stack = new Stack<>();
while(root!= null || stack.size()>0){
if (root!=null){
stack.push(root);
root = root.getLeftNode();
}else{
root = stack.pop();
printNode(root); //访问完左子树后,才可以访问根节点
root = root.getRightNode();
}
}
System.out.println();
}
输出结果为 :
中序遍历
1 2 3 4 5 6 7 8 9
后序遍历思路:
/**
* 后续遍历,递归方式.
* @param root 根节点
*/
public void postOrder(Node root){
if(root!=null){
postOrder(root.getLeftNode()); //后续遍历左子树
postOrder(root.getRightNode()); //后续遍历右子树
printNode(root); //访问根节点
}
}
/**
* 后续遍历,非递归方式.
* @param root 根节点
*/
public void postOrder_stack(Node root){
Stack stack = new Stack();
Stack output = new Stack<>();
stack.push(root);
while(stack.size()>0){
Node curr = stack.pop();
output.push(curr);
if(curr.getLeftNode()!=null){
stack.push(curr.getLeftNode());
}
if (curr.getRightNode()!=null){
stack.push(curr.getRightNode());
}
}
while(output.size()>0){
printNode(output.pop());
}
System.out.println();
}
输出结果为:
后续遍历
2 1 4 5 3 8 7 9 6
/**
* java实现二叉树前序、中序、后续遍历.
*/
public class BinaryTreeSearch {
public static void main(String[] args) {
BinaryTreeSearch treeSearch = new BinaryTreeSearch();
Node root = treeSearch.init();
System.out.println("前序遍历");
treeSearch.preOrder(root);
System.out.println();
treeSearch.preOrder_stack(root);
System.out.println("中序遍历");
treeSearch.inOrder(root);
System.out.println();
treeSearch.inOrder_stack(root);
System.out.println("后续遍历");
treeSearch.postOrder(root);
System.out.println();
treeSearch.postOrder_stack(root);
}
public void printNode(Node node){
System.out.print(node.getData()+" ");
}
/**
* 前序遍历,递归方法.
* @param root 根节点
*/
public void preOrder(Node root){
if (root!=null){
printNode(root); //访问根节点
preOrder(root.getLeftNode()); //前序遍历左子树
preOrder(root.getRightNode()); //前序遍历右子树
}
}
/**
* 前序遍历,非递归方法.
* @param root 根节点
*/
public void preOrder_stack(Node root){
Stack stack = new Stack<>();
while(root!=null || !stack.isEmpty()){
if(root!=null){
printNode(root); //访问根节点
stack.push(root); //入栈
root = root.getLeftNode(); //访问左子树
}else{
root = stack.pop(); //回溯至父节点
root = root.getRightNode(); //访问右子树
}
}
System.out.println();
}
/**
* 中序遍历,递归方式.
* @param root 根节点
*/
public void inOrder(Node root){
if (root!=null){
inOrder(root.getLeftNode()); //中序遍历左子树
printNode(root); //访问根节点
inOrder(root.getRightNode()); //中序遍历右子树
}
}
/**
* 中序遍历,非递归方式.
* @param root 根节点
*/
public void inOrder_stack(Node root){
Stack stack = new Stack<>();
while(root!= null || stack.size()>0){
if (root!=null){
stack.push(root);
root = root.getLeftNode();
}else{
root = stack.pop();
printNode(root); //访问完左子树后,才可以访问根节点
root = root.getRightNode();
}
}
System.out.println();
}
/**
* 后续遍历,递归方式.
* @param root 根节点
*/
public void postOrder(Node root){
if(root!=null){
postOrder(root.getLeftNode()); //后续遍历左子树
postOrder(root.getRightNode()); //后续遍历右子树
printNode(root); //访问根节点
}
}
/**
* 后续遍历,非递归方式.
* @param root 根节点
*/
public void postOrder_stack(Node root){
Stack stack = new Stack();
Stack output = new Stack<>();
stack.push(root);
while(stack.size()>0){
Node curr = stack.pop();
output.push(curr);
if(curr.getLeftNode()!=null){
stack.push(curr.getLeftNode());
}
if (curr.getRightNode()!=null){
stack.push(curr.getRightNode());
}
}
while(output.size()>0){
printNode(output.pop());
}
System.out.println();
}
public Node init(){
Node j = new Node(8,null,null);
Node h = new Node(4,null,null);
Node g = new Node(2,null,null);
Node f = new Node (7 ,null,j);
Node e = new Node (5,h,null);
Node d = new Node(1,null,g);
Node c = new Node(9 ,f,null);
Node b = new Node(3,d,e);
Node a = new Node(6,b,c);
return a ;
}
}
class Node{
private int data;
private Node leftNode;
private Node rightNode;
public Node(int data,Node leftNode,Node rightNode){
this.data= data;
this.leftNode = leftNode;
this.rightNode = rightNode;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftNode() {
return leftNode;
}
public void setLeftNode(Node leftNode) {
this.leftNode = leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setRightNode(Node rightNode) {
this.rightNode = rightNode;
}
}
1、通俗易懂讲解 二叉树遍历
2、Java实现二叉树先序,中序,后序遍历