二叉树中序遍历

二叉树中序遍历

中序遍历
顺序为:左子树->跟节点->右子树
先遍历左子树,然后遍历跟节点,最后遍历右子树,以此轮推,直到遍历完所有节点。

在这里插入图片描述

如上二叉树中序遍历结果为:1 2 3 4 5 6 7 8 9
一件很巧合的事情,遍历结果为一组已排序的序列,熟悉二叉搜索树的同学会发现,上边的二叉树其实是符合搜索二叉树。
二叉搜索树特征如下:
1.每个节点的值大于其左子树上所有节点的值(如果左子树不为空)
2.每个节点的值小于其右子树上所有节点的值(如果右子树不为空)
3.所有左子树和右子树自身也必须是二叉搜索树

检查如上二叉树结构,完全符合二叉树的所有特征,所以可以判定如上二叉树是一颗二叉搜索树。当把二叉树所有节点从左到右依次映射到一个序列中,所得到的序列即为一个按照升序排列的序列。
可以使用此方法来验证一颗二叉树,是否是一个二叉搜索树。

下面来说说二叉搜索树中序遍历逻辑:
中序遍历的顺序为:左子树->跟节点->右子树
要求如下:
1:每个节点的值只获取一次
2:如果节点有左子树,执行 1 之前要先获取左子树所有节点的值
3:执行 1 之后,如果节点有右子树,然后获取节点右树所有节点的值
4:所有节点值的获取,要遵守 1、2、3 条

实现方案有两种
一:递归实现
二:迭代实现

    // 节点定义如下
    public class TreeNode
    {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null)
        {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

递归实现如下

        public IList<int> InorderTraversal(TreeNode root)
        {
            // 集合存储访问节点的值
            IList<int> list = new List<int>();
            // 调用递归函数
            InorderTraversal(root, list);
            return list;
        }

        public void InorderTraversal(TreeNode node, IList<int> list)
        {
            if (null == node)
            {
                return;
            }

            // 递归调用左子树
            InorderTraversal(node.left, list);

            // 将节点值存储到集合中
            list.Add(node.val);

            // 递归访问右子树
            InorderTraversal(node.right, list);
        }

迭代实现如下

//迭代实现
        public IList<int> InorderTraversal2(TreeNode root)
        {
            // 集合存储访问节点的值
            IList<int> list = new List<int>();

            // 以栈结构(先进后出)来构建节点访问次序
            Stack<TreeNode> stack = new Stack<TreeNode>();

            // 先将跟节点入栈
            stack.Push(root);

            // 新建临时节点从 root 开始
            TreeNode node = root;
            while (stack.Count > 0)
            {
                // 迭代直到得到最深的左子树
                while (null != node && (null != node.left))
                {
                    stack.Push(node.left);
                    node = node.left;
                }

                // 节点出栈
                node = stack.Pop();
                if (null != node)
                {
                    // 将节点的值存入集合中
                    list.Add(node.val);

                    // 如果有子树不为空,则将右子树入栈
                    if (null != node.right)
                    {
                        stack.Push(node.right);
                    }
                    // 令节点等于其右子树,此时右子树可以为空
                    node = node.right;
                }
            }

            return list;
        }

至此二叉树中序遍历的原理以及实现均已奉上

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值