二叉树遍历算法之一:前序遍历

递归实现前序遍历

二叉树的前序遍历是指从根节点出发,按照先根节点,再左子树,后右子树的方法遍历二叉树中的所有节点,使得每个节点都被访问一次。

当调用遍历算法的时候前序遍历的具体过程如下:

  1. 首先访问根节点,如果根节点不为空,执行输出语句,打印根节点的值。
  2. 如果左子树不为空,则访问根节点的左孩子,并输出根节点做孩子的值
  3. 继续访问根节点的左孩子的左孩子,如果不为空则继续输出该左孩子的值;
  4. 如果这时左孩子为空,说明该节点是叶子节点,则按照先左孩子后右孩子的访问方式访问其左右孩子,如果不为空就打印输出
  5. 左子树访问完毕之后,继续访问根节点的右子树,如果根节点的右孩子不为空,则输出该右孩子
  6. 继续访问根节点右孩子的左孩子,如果不为空,则输出
  7. 接着访问根节点右孩子的右孩子,如果不为空,则输出

可以发现这个过程是不断循环进行的,可以使用递归算法实现,具体代码如下:

// 前序遍历的递归实现
    public void preOrderTraverse(TreeNode node) {
        if (node == null)
            return;
        // 先根节点
        System.out.println(node.val);
        // 再左孩子
        preOrderTraverse(node.left);
        // 后右孩子
        preOrderTraverse(node.right);
    }

为了测试使用,我构造一棵二叉树,先添加如下测试代码:

public static void main(String[] args) {
        TreeNode root = new TreeNode(8);
        TreeNode node1 = new TreeNode(6);
        TreeNode node2 = new TreeNode(10);
        TreeNode node3 = new TreeNode(5);
        TreeNode node4 = new TreeNode(7);
        TreeNode node5 = new TreeNode(9);
        TreeNode node6 = new TreeNode(11);
        TreeNode node7 = new TreeNode(15);
        TreeNode node8 = new TreeNode(24);
        TreeNode node9 = new TreeNode(30);
        TreeNode node10 = new TreeNode(28);

        root.left = node1;
        root.right = node2;
        node1.left = node3;
        node3.left = node7;
        node7.right = node8;
        node1.right = node4;
        node2.left = node5;
        node2.right = node6;
        node5.left = node9;
        node6.right = node10;

        TraverseTree t = new TraverseTree();
        t.preOrderTraverse(root);
    }

构造出来的二叉树是这样的:

二叉树遍历算法之一:前序遍历

所以根据前面的前序遍历算法遍历的结果应该是:8,6,5,15,24,7,10,9,30,11,28

非递归方式实现前序遍历

递归代码很简洁,但是也有一些不是很好理解,能不能直接使用循环的方法加以解决呢?采用非递归的思路其实与上面是一致的,不过在遍历的过程中需要使用一些额外的空间保存遍历的中间结果,下面是使用非递归的方式实现前序遍历的代码:

// 前序遍历的非递归实现
    public void preOrderTraverse2(TreeNode node) {
        if (node == null) return;
        //创建一个栈用于保存遍历的结点
        Stack<TreeNode> s = new Stack<TreeNode>();
        while(node != null || !s.isEmpty()){
            //遍历左子树
            while(node != null){
                System.out.print(node.val + " ");
                s.push(node);
                node = node.left;
            }
            //遍历右子树
            if(!s.isEmpty()){
                node = s.pop();
                node = node.right;
            }
        }
    }
上一篇:《大数据原理:复杂信息的准备、共享和分析》一一第1章 为非结构化数据提供结构


下一篇:MaxCompute - ODPS重装上阵 第一弹 - 善用MaxCompute编译器的错误和警告