• 数据结构 递归和非递归方式实现二叉树先序、中序和后序遍历


      二叉树的先序遍历顺序是根、左、右;中序遍历顺序是左、根、右;后序遍历顺序是左、右、根。

      递归方式实现如下:

     1 public class TreeNode {
     2     private int value;
     3     private TreeNode left, right;
     4     
     5     public TreeNode(int data) {
     6         value = data;
     7     }
     8     
     9     // 递归方式实现先序遍历
    10     public void preorder(TreeNode treeNode) {
    11         if (treeNode == null) {
    12             return;
    13         }
    14         
    15         System.out.println(treeNode.value + " ");
    16         preorder(treeNode.left);
    17         preorder(treeNode.right);
    18     }
    19     
    20     // 递归方式实现中序遍历
    21     public void inorder(TreeNode treeNode) {
    22         if (treeNode == null) {
    23             return;
    24         }
    25         
    26         inorder(treeNode.left);
    27         System.out.println(treeNode.value + " ");
    28         inorder(treeNode.right);
    29     }
    30     
    31     // 递归方式实现后序遍历
    32     public void postorder(TreeNode treeNode) {
    33         if (treeNode == null) {
    34             return;
    35         }
    36         
    37         postorder(treeNode.left);
    38         postorder(treeNode.right);
    39         System.out.println(treeNode.value + " ");
    40     }
    41 }

      递归方式能解决的问题都能用非递归方式来解决,因为递归方式通过函数栈来保存信息,普通的栈或队列也能达到相同效果。

      

      非递归方式实现先序遍历,参考【经典面试题二】二叉树的递归与非递归遍历(前序、中序、后序)

      

      非递归方式实现中序遍历,步骤如下:

      1 如果当前结点为空,则结束。

      2 创建实现了Deque接口的LinkedList对象,引用为stack。

      3 当前结点入栈,左孩子结点不断入栈,直到没有左孩子结点。

      4 栈顶结点出栈,打印其结点值。如果有右孩子结点,则把它设为当前结点;否则,重复该步骤,直到有右孩子结点或者stack为空。

      5 重复步骤3和4。

      Java代码:

     1 // 非递归方式实现中序遍历
     2 public void inOrder(TreeNode cur) {
     3     if (cur != null) {
     4         Deque<TreeNode> stack = new LinkedList<TreeNode>();
     5         while (true) {
     6             // 已保证当前结点非空
     7             stack.addFirst(cur);
     8             for (cur = cur.left; cur != null; cur = cur.left) {
     9                 stack.addFirst(cur);
    10             }
    11             
    12             while (true) {
    13                 // 当前结点出栈并打印
    14                 cur = stack.removeFirst();
    15                 System.out.println(cur.value + " ");
    16                 
    17                 TreeNode right = cur.right;
    18                 if (right != null) {
    19                     cur = right;
    20                     break;
    21                 } else if (stack.isEmpty()) {
    22                     return;
    23                 }
    24             }
    25         }
    26     }
    27 }

      

      非递归方式实现后序遍历,步骤如下:

      1 如果当前结点为空,则结束。

      2 创建两个实现了Deque接口的LinkedList对象,引用分别为stack1和stack2。

      3 当前结点入栈stack1。

      4 stack1栈顶结点出栈,该结点入栈stack2,该结点的非空左右孩子结点入栈stack1。

      5 重复步骤4,直到stack1为空。

      6 stack2栈顶结点出栈,打印其结点值,重复该步骤,直到stack2为空。

      Java代码:

     1 // 非递归方式实现后序遍历
     2 public void postOrder(TreeNode cur) {
     3     if (cur != null) {
     4         Deque<TreeNode> stack1 = new LinkedList<TreeNode>();
     5         Deque<TreeNode> stack2 = new LinkedList<TreeNode>();
     6         
     7         stack1.addFirst(cur);
     8         while (!stack1.isEmpty()) {
     9             cur = stack1.removeFirst();
    10             stack2.addFirst(cur);
    11             
    12             TreeNode left = cur.left, right = cur.right;
    13             if (left != null) {
    14                 stack1.addFirst(left);
    15             }
    16             if (right != null) {
    17                 stack1.addFirst(right);
    18             }
    19         }
    20         
    21         while (!stack2.isEmpty()) {
    22             System.out.println(stack2.removeFirst().value + " ");
    23         }
    24     }
    25 }

      参考资料

      《程序员代码面试指南 IT名企算法与数据结构题目最优解》P88-95

  • 相关阅读:
    在PictureBox中打开图片文件
    while和do-while语句的异同之处
    if选择语句与switch选择语句的比较、区别及应用场景
    二进制数的原码 反码 补码的作用及转换
    一篇文章看懂二进制、八进制、十进制、十六进制数据转换
    ASCII,unicode, utf8 ,big5 ,gb2312,gbk,gb18030等几种常用编码区别(转载)
    百钱买百鸡问题
    鸡兔同笼问题
    用for循环打印九九乘法表(for嵌套循环)
    用*号打印直角三角形(正反)
  • 原文地址:https://www.cnblogs.com/WJQ2017/p/8449573.html
Copyright © 2020-2023  润新知