之前一篇文章写了二叉树遍历的一些东西,但是自己写完还是有些不理解,或者说就没吃透,经过多方查找,终于找到了在我看来的终极解决方案。
这次说的是非递归的算法,二叉树遍历分为三种,不论是递归还是非递归都是依照这三种规则实现的:
前序:根 左 右
中序:左 根 右
后续:左 右 根
先说一下想法吧,主要是用栈来实现:这种算法要求二叉树类除了val、left
right之外,还要有一个标示。在下面的算法实现里有涉及
1、初始化栈
1.1 将根结点入栈
2、循环:while(栈不为空)
2.1 弹出栈顶元素
2.2 判断弹出元素的flag是否为真 1 --真的话,输出 执行下一轮循环
2.3 2.2为假的话,先将该结点的flag置为真 1
2.4 依次将该结点的右结点、左结点、根结点入栈–先判断根的左右结点是否为空
以上是前序遍历的实现,我之所以说这是终极方案,是因为中序、后序的算法实现在前序算法的实现上改变不大,且有规则!主要变化发生在2.4步,在前序遍历中,2.4操作的顺序就是前序规则的倒序!!!那这样,我们就知道了,其他两种遍历也是相对应规则的倒序!下面把对应规则写出来:
前序 根左右 -->2.4 规则 右左根
中序 左根右 -->2.4 规则 右根左
后序 左右根 -->2.4 规则 根右左
下面是三个算法:
二叉树类:

public class BinaryTree {
    int data;
    BinaryTree left;
    BinaryTree right;
    //和其他算法相比增加了一个标示
    int flag;
    public BinaryTree(int data)    //实例化二叉树类
    {
        this.data = data;
        this.left = null;
        this.right = null;
        this.flag = 0;
    }
}

前序遍历:

/**
     * 先序遍历
     */
    public static String preOrder(BinaryTree root){
        Stack<BinaryTree> stack = new Stack<BinaryTree>(); //初始化栈
        stack.push(root); //将根结点入栈
        BinaryTree binaryTree = null;
        StringBuilder str = new StringBuilder("");
        while(!stack.isEmpty()){ //循环:while(栈不为空)
            binaryTree = stack.pop(); //弹出栈顶元素
            if(binaryTree.flag == 1){ //判断弹出元素的flag是否为真 1 --真的话,输出 执行下一轮循环
                str.append(binaryTree.data + "-");
                continue;
            }else{
                binaryTree.flag = 1; //为假的话,先将该结点的flag置为真 1
                
                //依次将该结点的右结点、左结点、根结点入栈--先判断根的左右结点是否为空
                if(binaryTree.right != null){
                    stack.push(binaryTree.right);
                }
                if(binaryTree.left != null){
                    stack.push(binaryTree.left);
                }
                stack.push(binaryTree);
            }
        }
        return str.toString();
    }