二叉树的遍历(递归实现与非递归实现java)

二叉树的遍历递归实现比较简单

二叉树的非递归实现

  先根遍历

  中根遍历(两种实现方式)

  后根遍历(比较复杂)

package com.sun.util;

import java.lang.reflect.Method;
import java.util.*;

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
    public TreeNode(int x){
        val=x;
    }
    public TreeNode getLeft() {
        return left;
    }
    public void setLeft(TreeNode left) {
        this.left = left;
    }
    public TreeNode getRight() {
        return right;
    }
    public void setRight(TreeNode right) {
        this.right = right;
    }
    
}
public class Solution {
    
    public TreeNode[] initTree(){
        TreeNode[] tree=new TreeNode[11];
        for(int i=0;i<tree.length;i++){
            tree[i]=new TreeNode(i+1);
        }
        tree[0].left=tree[1];
        tree[0].right=tree[2];
        tree[1].left=tree[3];
        tree[1].right=tree[4];
        tree[2].left=tree[5];
        tree[2].right=tree[6];
        
//        tree[4].left=tree[7];
//        tree[3].right=tree[8];
//        
//        tree[8].left=tree[9];
//        tree[8].right=tree[10];
        
        tree[4].left=tree[7];
        tree[4].right=tree[8];
        
        tree[8].left=tree[9];
        tree[8].right=tree[10];
        return tree;
        
    }
    
//    一递归遍历
//    1.先根遍历
    public void preOrderRecursion(TreeNode root, List<Integer> nodeList){
        if (root!=null){
            nodeList.add(root.val);
            preOrderRecursion(root.left, nodeList);
            preOrderRecursion(root.right,nodeList);
        }
        
    }
//    2.中根遍历
    public void inOrderRecursion(TreeNode root, List<Integer> nodeList){
        if (root!=null){
            inOrderRecursion(root.left, nodeList);
            nodeList.add(root.val);
            inOrderRecursion(root.right,nodeList);
        }
        
    }
//    3.后根遍历
    public void afterOrderRecursion(TreeNode root, List<Integer> nodeList){
        if (root!=null){
            afterOrderRecursion(root.left, nodeList);
            afterOrderRecursion(root.right,nodeList);
            nodeList.add(root.val);
        }
        
    }
//    二 非递归遍历(栈实现)
            
//    1.先根遍历_1
    public void preOrderStack(TreeNode root, List<Integer> nodeList){
        Stack<TreeNode> nodeStack = new Stack<TreeNode>();
        TreeNode currentNode=root;
        while(!nodeStack.isEmpty()||currentNode!=null){
            while(currentNode!=null){
                nodeList.add(currentNode.val);System.out.println(currentNode.val);
                nodeStack.push(currentNode);
                currentNode=currentNode.left;
            }
            if(!nodeStack.isEmpty()){
                currentNode = nodeStack.pop();
                currentNode = currentNode.right;
            }
        }
    }    
        
    
//    2.中根遍历_1
    public void inOrderStackOne(TreeNode root, List<Integer> nodeList){
        Stack<TreeNode> nodeStack = new Stack<TreeNode>();
        nodeStack.push(root);
        TreeNode peekNode,popNode;
        while(!nodeStack.isEmpty()){// 第一个while循环
            peekNode = nodeStack.peek();
            while(peekNode!=null){// 第二个while循环
                nodeStack.push(peekNode.left);
                peekNode=nodeStack.peek();
            }
            nodeStack.pop();
            if(!nodeStack.isEmpty()){ 
                // 这个if判断主要是因为,当最后一个节点pop出战之后,还会把最后一个节点的右孩子入站,但是值为null,
                //导致会进入第一个while循环,不会进入第二个while循环,详细解释如下:
                /*当popNode为最后一个遍历到的节点的时候, 
                nodeStack.push(popNode.right);使栈还存在一个null,栈不为空,
                可以进入第一个while循环,
                但是此时由于栈里面的元素只剩下null,所以peekNode=nodeStack.peek()=null
                不会进入的二个while循环
                当执行到nodeStack.pop()之后,此时栈为空,这个时候就应该停止算法了.如果不加if条件,则会进入if体内,再次调用nodeStack.pop()出错
                */
                popNode = nodeStack.pop();
                nodeList.add(popNode.val);
                nodeStack.push(popNode.right);
            }
        }
    }
    
//    2.中根遍历_2
    public void inOrderStackTwo(TreeNode root, List<Integer> nodeList){
        Stack<TreeNode> nodeStack = new Stack<TreeNode>();
        TreeNode currentNode=root;
        while(!nodeStack.isEmpty()||currentNode!=null){
            while(currentNode!=null){
                nodeStack.push(currentNode);
                currentNode=currentNode.left;
            }
            if(!nodeStack.isEmpty()){
                currentNode = nodeStack.pop();
                nodeList.add(currentNode.val);//System.out.println(currentNode);
                currentNode = currentNode.right;
            }
        }        
    }    
//     3.后根遍历
    public void afterOrderStack(TreeNode root, List<Integer> nodeList){
        Stack<TreeNode> nodeStack = new Stack<TreeNode>();
        TreeNode currentNode=root,peekNode,popNode,rightNode;
        while(!nodeStack.isEmpty()|| currentNode!=null ){// 第一个while循环
            while(currentNode!=null){// 第二个while循环
                nodeStack.push(currentNode);
                currentNode = currentNode.left;
            }
            boolean flag=true;// 右孩子没有访问过的标志
            rightNode=null;
            while(!nodeStack.isEmpty()&&flag) {
                peekNode = nodeStack.peek();
                if (peekNode.right==rightNode) {
                    popNode = nodeStack.pop();
                    nodeList.add(popNode.val);//System.out.println(popNode.val);
                    if(nodeStack.isEmpty()){
                        return;
                    }else{
                        rightNode=popNode;
                    }
                }else{
                    currentNode = peekNode.right;
                    flag=false;
                }
            }
        }
    }
    public static void main(String[] args){
        
        Solution answer = new Solution();
        TreeNode[] tree = answer.initTree();
        List<Integer> nodeList = new ArrayList<Integer>();
        
        System.out.println("递归算法:");
        System.out.print("	先根遍历	");
        answer.preOrderRecursion(tree[0], nodeList);
        nodeList.forEach(System.out::print);
//        
        System.out.print("
	中根遍历	");
        nodeList.clear();
        answer.inOrderRecursion(tree[0], nodeList);
        nodeList.forEach(System.out::print);
//        
        System.out.print("
	后根遍历	");
        nodeList.clear();
        answer.afterOrderRecursion(tree[0], nodeList);
        nodeList.forEach(System.out::print);
//        
        System.out.print("
非递归算法:");//        
        System.out.print("
	先根遍历	");
        nodeList.clear();
        answer.preOrderStack(tree[0], nodeList);
        nodeList.forEach(System.out::print);

        System.out.print("
	中根遍历1	");
        nodeList.clear();
        answer.inOrderStackOne(tree[0], nodeList);
        nodeList.forEach(System.out::print);
        
        System.out.print("
	中根遍历2	");
        nodeList.clear();
        answer.inOrderStackTwo(tree[0], nodeList);
        nodeList.forEach(System.out::print);

        System.out.print("
	后根遍历	");
        nodeList.clear();
        answer.afterOrderStack(tree[0], nodeList);
        nodeList.forEach(System.out::print);
        
    }

}
递归算法:
    先根遍历    1245891011367
    中根遍历    4285109111637
    后根遍历    4810119526731
非递归算法:
    先根遍历    1245891011367
    中根遍历1    4285109111637
    中根遍历2    4285109111637
    后根遍历    4810119526731
原文地址:https://www.cnblogs.com/sunupo/p/13409400.html