zoukankan      html  css  js  c++  java
  • 二叉树的先序、中序、后序遍历-递归and非递归版本

      1 package com.gc.study.art;
      2 
      3 import java.util.ArrayList;
      4 import java.util.List;
      5 
      6 /**
      7  * 树的前序、中序、后序遍历
      8  * @author gc
      9  *      1
     10  *   2         3
     11  * 4   5  6   7
     12  * 
     13  * 先序遍历:1 2 4 5 3 6 7
     14  * 中序遍历:4 2 5 1 6 3 7
     15  * 后序遍历:4 5 2 6 7 3 1
     16  */
     17 public class TreePost {
     18     public static void main(String[] args) {
     19         TreePost tree = new TreePost();
     20 
     21         
     22         List<Integer> rs = new ArrayList<Integer>();
     23         tree.pre(tree.getRoot(), rs);
     24         System.out.println("先序遍历(递归版本):" + rs);
     25         
     26         rs.clear();
     27         tree.mid(tree.getRoot(), rs);
     28         System.out.println("中序遍历(递归版本):" + rs);
     29         rs.clear();
     30         tree.post(tree.getRoot(), rs);
     31         System.out.println("后序遍历(递归版本):" + rs);
     32         
     33         System.out.println("先序遍历:" + tree.preorderTraversal(tree.getRoot()));
     34         System.out.println("中序遍历:" + tree.inorderTraversal(tree.getRoot()));
     35         System.out.println("后序遍历:" + tree.postorderTraversal(tree.getRoot()));
     36 
     37     }
     38 
     39     /**
     40      * 构造测试数据
     41      * 
     42      * @return
     43      */
     44     public TreeNode getRoot() {
     45         TreeNode root = new TreeNode(1);
     46         root.left = new TreeNode(2);
     47         root.right = new TreeNode(3);
     48         root.left.left = new TreeNode(4);
     49         root.left.right = new TreeNode(5);
     50         root.right.left = new TreeNode(6);
     51         root.right.right = new TreeNode(7);
     52         return root;
     53     }
     54 
     55     /**
     56      * 先序遍历
     57      * 思想:先左后又,左到低,右取1不丢弃,入队列时取其值(入队列的数据正好符合先序遍历)
     58      * @param root
     59      * @return
     60      */
     61     public List<Integer> preorderTraversal(TreeNode root) {
     62         List<Integer> rs = new ArrayList<Integer>();
     63         if (root == null) {
     64             return rs;
     65         }
     66         List<TreeNode> nodes = new ArrayList<TreeNode>();
     67         nodes.add(root);
     68         TreeNode cur = root;
     69         rs.add(cur.val);
     70         while (cur != null) {
     71             //一直遍历,直到把最左边的数据加到数组中(同时打印加入的节点)
     72             while (cur.left != null) {
     73                 nodes.add(cur.left);
     74                 cur.left = null;
     75                 cur = nodes.get(nodes.size() - 1);
     76                 rs.add(cur.val);
     77             }
     78             //将当前节点的右节点加到数组中(并且可以打印当前节点的值)
     79             if (cur.right != null) {
     80                 nodes.add(cur.right);
     81                 cur.right = null;
     82                 cur = nodes.get(nodes.size() - 1);
     83                 rs.add(cur.val);
     84             } else {
     85                 //当前节点没有右节点,直接移除
     86                 nodes.remove(cur);
     87             }
     88             
     89             cur = getLast(nodes);
     90 
     91         }
     92         return rs;
     93     }
     94 
     95     /**
     96      * 中序遍历
     97      * 思想:先左后右,左到低,右取1不丢弃,出队列时取其值(取值并移除)
     98      * @param root
     99      * @return
    100      */
    101     public List<Integer> inorderTraversal(TreeNode root) {
    102         List<Integer> rs = new ArrayList();
    103         if (root == null) {
    104             return rs;
    105         }
    106         List<TreeNode> nodes = new ArrayList<TreeNode>();
    107         nodes.add(root);
    108         TreeNode cur = root;
    109         while (cur != null) {
    110             while (cur.left != null) {
    111                 nodes.add(cur.left);
    112                 cur.left = null;
    113                 cur = getLast(nodes);
    114             }
    115 
    116             rs.add(cur.val);
    117             nodes.remove(cur);
    118 
    119             if (cur.right != null) {
    120                 nodes.add(cur.right);
    121                 cur.right = null;
    122                 cur = getLast(nodes);
    123             } 
    124             
    125             cur = getLast(nodes);
    126         }
    127         return rs;
    128     }
    129 
    130     /**
    131      * 迭代算法
    132      * 思想:先左后右,左到低,孩子为空取其值(取值并移除)
    133      * @param root
    134      * @return
    135      */
    136     public List<Integer> postorderTraversal(TreeNode root) {
    137         List<Integer> rs = new ArrayList<Integer>();
    138         if (root == null) {
    139             return rs;
    140         }
    141         List<TreeNode> nodes = new ArrayList<TreeNode>();
    142         nodes.add(root);
    143         TreeNode cur = root;
    144 
    145         while (cur != null) {
    146 
    147             while (cur.left != null) {
    148                 nodes.add(cur.left);
    149                 cur.left = null;
    150                 cur = nodes.get(nodes.size() - 1);
    151             }
    152 
    153             if (cur.right != null) {
    154                 nodes.add(cur.right);
    155                 cur.right = null;
    156                 cur = nodes.get(nodes.size() - 1);
    157             }
    158 
    159             if (cur.left == null && cur.right == null) {
    160                 rs.add(cur.val);
    161                 nodes.remove(cur);
    162                 cur = getLast(nodes);
    163             }
    164 
    165         }
    166         return rs;
    167     }
    168     
    169     /**
    170      * 先序遍历递归版本
    171      * @param node
    172      * @param rs
    173      */
    174     public void pre(TreeNode node, List<Integer> rs) {
    175         if(node == null) {
    176             return;
    177         }
    178         rs.add(node.val);
    179         pre(node.left, rs);
    180         pre(node.right, rs);
    181     }
    182     /**
    183      * 中序遍历递归版本
    184      * @param node
    185      * @param rs
    186      */
    187     public void mid(TreeNode node, List<Integer> rs) {
    188         if(node == null) {
    189             return;
    190         }
    191         mid(node.left, rs);
    192         rs.add(node.val);
    193         mid(node.right, rs);
    194     }
    195     /**
    196      * 后续遍历递归版本
    197      * @param node
    198      * @param rs
    199      */
    200     public void post(TreeNode node, List<Integer> rs) {
    201         if(node == null) {
    202             return;
    203         }
    204         post(node.left, rs);
    205         post(node.right, rs);
    206         rs.add(node.val);
    207     }
    208     /**
    209      * 获取上一个节点
    210      * 
    211      * @param nodes
    212      * @return
    213      */
    214     private TreeNode getLast(List<TreeNode> nodes) {
    215         if (nodes.size() > 0) {
    216             return nodes.get(nodes.size() - 1);
    217         } else {
    218             return null;
    219         }
    220     }
    221 
    222     public static class TreeNode {
    223         int val;
    224         TreeNode left;
    225         TreeNode right;
    226 
    227         TreeNode(int x) {
    228             val = x;
    229         }
    230 
    231         @Override
    232         public String toString() {
    233             // TODO Auto-generated method stub
    234             return String.valueOf(val);
    235         }
    236     }
    237 }
  • 相关阅读:
    New Skateboard
    1127
    一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    vim 快捷键绑定
    使用git 上传项目到gitee/github
    Linux进程/线程调度策略与 进程优先级
    【框架】共享内存组设计思路与实现(更新中)
    linux下六大IPC机制【转】
    详解Linux内核红黑树算法的实现
    Linux 内核里的数据结构:红黑树(rb-tree)
  • 原文地址:https://www.cnblogs.com/gc65/p/12694604.html
Copyright © 2011-2022 走看看