当前位置: 首页 > news >正文

二叉树遍历算法之二:中序遍历

中序遍历的递归实现

中序遍历遍历指的是先访问二叉树中节点的左孩子,再访问当前节点,最后再访问其右孩子。具体访问步骤如下:

  1. 首先访问根节点,判断根节点是否有左孩子,如果有,进行第二步;如果没有,跳到第三步;
  2. 访问左孩子,继续判断当前节点是否有左孩子,如果有则继续访问其左孩子,直到某节点的左孩子为空
  3. 判断是否有右孩子,如果有,则继续判断当前节点是否有左孩子,一直到某节点没有左孩子为止
  4. 把第二步访问的节点做为当前节点(该节点无左孩子,如图中的15节点),按照规则,下一步应该访问其右孩子
  5. 返回到第四部节点的双亲节点(15的双亲节点是5),并设为当前访问的节点,下一步访问的是其右孩子(这里5没有右孩子)
  6. 继续访问第五步访问节点的双亲节点(5的双亲节点是6),下一步仍然访问其右孩子。
  7. 左子树访问完毕,继续第三步中右子树的访问,步骤与上面一直,最终每个节点都将访问一遍

仍然以上一篇博客中前序遍历的例子作为说明:

二叉树

按照中序遍历的访问规则,最终的输出序列应该是15,24,5,6,7,8,30,9,10,11,28

可以发现这是一个递归过程,其递归代码也很简单,代码如下:

package com.rhwayfun.algorithm.tree;

public class TravelTree {

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int val) {
            this.val = val;
        }
    }

    public void inOrderTraverse(TreeNode node) {
        if (node == null)
            return;
        inOrderTraverse(node.left);
        System.out.print(node.val + " ");
        inOrderTraverse(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;

        new TravelTree().inOrderTraverse(root);
    }
}

中序遍历的非递归实现

下面我们讨论一下非递归实现,与上一篇前序遍历的非递归实现由一些类是,主要的访问次序的改变,所以只需要在前面代码的基础上做一些适当修改就可以了,下面是对中序遍历代码的实现(经测试可用):

public void inOrderTraverse2(TreeNode node){
        Stack<TreeNode> s = new Stack<TreeNode>();
        while(node != null || !s.isEmpty()){
            //遍历左子树
            while(node != null){
                s.push(node);
                node = node.left;
            }
            //遍历右子树
            if(!s.isEmpty()){
                node = s.pop();
                System.out.print(node.val + " ");
                node = node.right;
            }
        }
    }

相关文章:

  • The network connection was lost.
  • 网络编程使用代理方法 , 简化请求和响应
  • jsp的标签和EL表达式
  • DEBUG命令详细说明
  • 网页中多个图标在一张图片上,使用css将各图标显示
  • C++容易忽略的细节
  • vim+ctags+cscope 常用技巧和命令
  • IT公司100题-13-求链表中倒数第k个结点
  • Log aggregation has not completed or is not enabled.
  • linux安装scikit-learn
  • JavaMail:搜索、过滤接收邮件,删除邮件
  • 对JS继承的一点思考
  • 成为一名优秀的Developer的书单
  • HDU ACM 2586 How far away ?LCA-gt;并查集+Tarjan(离线)算法
  • php正则获取网页标题、关键字、网页描述代码
  • [译]前端离线指南(上)
  • C++类的相互关联
  • const let
  • gitlab-ci配置详解(一)
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • orm2 中文文档 3.1 模型属性
  • springMvc学习笔记(2)
  • Spring核心 Bean的高级装配
  • Spring框架之我见(三)——IOC、AOP
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 面试遇到的一些题
  • 前端学习笔记之观察者模式
  • 写给高年级小学生看的《Bash 指南》
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 《码出高效》学习笔记与书中错误记录
  • gunicorn工作原理
  • kubernetes资源对象--ingress
  • Nginx实现动静分离
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​VRRP 虚拟路由冗余协议(华为)
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1)bark-ml
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (C++17) std算法之执行策略 execution
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (九十四)函数和二维数组
  • (一)Linux+Windows下安装ffmpeg
  • (转)ABI是什么
  • (转)使用VMware vSphere标准交换机设置网络连接
  • .NET Core 版本不支持的问题
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .net通用权限框架B/S (三)--MODEL层(2)
  • [ linux ] linux 命令英文全称及解释
  • [4.9福建四校联考]
  • [ACM] hdu 1201 18岁生日
  • [BIZ] - 1.金融交易系统特点
  • [BZOJ 3680]吊打XXX(模拟退火)
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体