二叉树的中序遍历

21 篇文章 0 订阅

给定一个二叉树,返回它的中序 遍历

示例:

输入: [1,null,2,3]

   1
    \
     2
    /
   3

输出: [1,3,2]

递归:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {

        List<Integer> list = new LinkedList<>();

        inorder(root, list);

        return list;

    }

    public void inorder(TreeNode root, List<Integer> list){

        if(root != null){

            if(root.left != null) inorder(root.left, list);

            list.add(root.val);

            if(root.right != null) inorder(root.right, list);

        }

    } 

}

迭代

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {


        Stack <TreeNode> stack = new Stack<TreeNode>();

        List<Integer> list = new LinkedList<>();
		
		//把node看做一个指针
        TreeNode node = root;
        
		//node == null时 此子树已经走完,返回上一节点
        while(node != null || !stack.isEmpty()){

                //寻找最左的节点
                while(node != null){

                    stack.push(node);
                    node = node.left;
                }

               //弹出,它已经没有左子树了,可以看做中间节点
               //node不存在的话,这一步是返回上一节点
                node = stack.pop();
				
				
                list.add(node.val);
				
				//如果有右子树的话,遍历右子树,没有的话,返回上一节点
                node = node.right;

            }
            

        return list;

    }
}

莫里斯遍历

本方法中,我们使用一种新的数据结构:线索二叉树。方法如下:

Step 1: 将当前节点current初始化为根节点

Step 2: While current不为空,

若current没有左子节点

a. 将current添加到输出

b. 进入右子树,亦即, current = current.right

否则

a. 在current的左子树中,令current成为最右侧节点的右子节点

b. 进入左子树,亦即,current = current.left

举例而言:

      1
    /   \
   2     3
  / \   /
 4   5 6

首先,1 是根节点,所以将 current 初始化为 1。1 有左子节点 2,current 的左子树是

     2
    / \
   4   5

在此左子树中最右侧的节点是 5,于是将 current(1) 作为 5 的右子节点。令 current = cuurent.left (current = 2)。
现在二叉树的形状为:

     2
    / \
   4   5
        \
         1
          \
           3
          /
         6

对于 current(2),其左子节点为4,我们可以继续上述过程

    4
     \
      2
       \
        5
         \
          1
           \
            3
           /
          6

由于 4 没有左子节点,添加 4 为输出,接着依次添加 2, 5, 1, 3 。节点 3 有左子节点 6,故重复以上过程。
最终的结果是 [4,2,5,1,6,3]。

class Solution {
    public List < Integer > inorderTraversal(TreeNode root) {
        List < Integer > res = new ArrayList < > ();
        TreeNode curr = root;
        TreeNode pre;
        while (curr != null) {
            if (curr.left == null) {
                res.add(curr.val);
                curr = curr.right; // move to next right node
            } else { // has a left subtree
                pre = curr.left;
                while (pre.right != null) { // find rightmost
                    pre = pre.right;
                }
                pre.right = curr; // put cur after the pre node
                TreeNode temp = curr; // store cur node
                curr = curr.left; // move cur to the top of the new tree
                temp.left = null; // original cur left be null, avoid infinite loops
            }
        }
        return res;
    }
}



作者:LeetCode
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值