二叉树三种遍历递归及非递归实现

来源:互联网 发布:amd开源驱动知乎 编辑:程序博客网 时间:2024/05/19 21:41

二叉树的三种遍历方式包括:

  1. 前序遍历
  2. 中序遍历
  3. 后序遍历

三种遍历的递归方法都非常好实现,而且简单易懂。非递归实现也是通过使用来模拟遍历的过程。顺便提一句,能用递归做的,基本都能用栈来实现。前序遍历和中序遍历的非递归写法相对比较简单,只需要模拟遍历过程即可。后序遍历非递归写法比较难,需要借助一个辅助指针来记录右子树是否访问过,以防止重复访问陷入死循环。下面分别给出三种遍历方法的递归非递归实现的代码:

前序遍历

递归:

public void PreOrderTraversal(TreeNode root) {    if (root == null) {        return;    }    System.out.print(root.val);    if (root.left != null) {        PreOrderTraversal(root.left);    }    if (root.right != null) {        PreOrderTraversal(root.right);    }}


非递归:

public void PreOrderTraversal2(TreeNode root){    Stack<TreeNode> stack = new Stack<>();    TreeNode node;    if (root == null) {        return;    }    stack.push(root);    while (!stack.empty()) {        node = stack.pop();        System.out.print(node.val);        if (node.right != null) {            stack.push(node.right);        }        if (node.left != null) {            stack.push(node.left);        }//end if    }}

将根节点放入栈中,当栈不空时,取出栈顶元素x,访问x的值,如果x的左孩子不为空,将其左孩子入栈;如果其右孩子不为空,将其右孩子入栈,直至栈空。

中序遍历

递归:

public void InOrderTraversal(TreeNode root) {    if (root == null) {        return;    }    if (root.left != null) {        InOrderTraversal(root.left);    }    System.out.print(root.val);    if (root.right != null) {        InOrderTraversal(root.right);    }}

非递归:

public void InOrderTraversal2(TreeNode root) {    if (root == null) {        return;    }    TreeNode node;    Stack<TreeNode> stack = new Stack<>();    stack.push(root);    node = root.left;    while ((node != null)||(!stack.empty())) {        while (node != null) {            stack.push(node);            node = node.left;        }        node = stack.pop();        System.out.print(node.val);        node = node.right;    }}



1、先遍历到二叉树的最左结点

2、弹出栈顶元素x并访问

3、考察x的右子树是否为空,如果为空则执行2,否则将当前结点设为x的右子树并执行1.

后序遍历

递归:

public void PostOrderTraversal(TreeNode root) {    if (root == null) {        return;    }    if (root.left != null) {        PostOrderTraversal(root.left);    }    if (root.right != null) {        PostOrderTraversal(root.right);    }    System.out.print(root.val);}

非递归:

public void PostOrderTraversal2(TreeNode root) {    if (root == null) {        return;    }    Stack<TreeNode> stack = new Stack<>();    stack.push(root);    TreeNode node = root.left;    TreeNode lastVisit = null;    while (node != null) {        stack.push(node);        node = node.left;    }    while (!stack.empty()) {        node = stack.pop();        if (node.right == null || node.right == lastVisit) {            System.out.print(node.val);            lastVisit = node;        } else {            stack.push(node);            node = node.right;            while (node != null) {                stack.push(node);                node = node.left;            }        }    }}

后序遍历非递归做法需要设置一个指针lastVisit指向上次输出的元素。

1、从根节点开始遍历到最左节点

2、当栈不空时弹出栈顶元素

3、如果栈顶元素x的右子树为空或者x的右子树等于lastVisit说明该右子树已经访问过,访问当前节点x并将lastVisit指向x。

否则将x压回栈中,并且将当前节点指向x的右子树,执行步骤1.









0 0
原创粉丝点击