递归和栈方法实现二叉树前后中序遍历及Morris遍历方法(java)

递归实现优点,简单,本质上也是用栈实现。

树结构定义:

/**
 * 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>   ret=new ArrayList<>();
        Stack<TreeNode> stack=new Stack<>();
        while(root!=null||!stack.isEmpty()){
            while(root!=null){
                stack.push(root);
                root=root.left;
            }
            root=stack.pop();
            ret.add(root.val);
            root=root.right;
        }
        return ret;
    }
}

递归方法

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer>   ret=new ArrayList<>();
        return help(root,ret);
    
    }
    private List<Integer> help(TreeNode root,List<Integer> a){
        if(root==null)
            return a;
        help(root.left,a);
        a.add(root.val);
        help(root.right,a);
        return a;
    }
}

Morris遍历,时间复杂度O(N),空间复杂度O(1),
关于Morris遍历,详细解释可看这里:
https://www.jianshu.com/p/959247c29a7b
https://www.jianshu.com/p/484f587c967c

/**
 * 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>   ret=new ArrayList<>();
        TreeNode current=root;
        while(current!=null){
           if(current.left==null){          //如果左子树为空
               ret.add(current.val);            //假如当前结点并进入右边节点    
               current=current.right;   
           }
           else{                            //左子树不为空,找他的前序结点
               TreeNode temp=current.left;
    while(temp.right!=null&&temp.right!=current){  
         //找最右结点,并且不是指向current的最右结点
                    temp=temp.right;
               }
            if(temp.right==null){           //最右结点还没指向current时
                temp.right=current;
                current=current.left;       //进入他的左子树
            }
            else{                            //要是指向了当前节点自己
                temp.right=null;
                ret.add(current.val);        //打印curr的值
                current=current.right;       //左边遍历完毕 ,遍历右边
            }

           }
        }
        return ret;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44137260/article/details/104426521
今日推荐