前序遍历-中序遍历-后序遍历,是二叉树中常见的三种遍历方式,实现这三种遍历方式的常用方法是递归和迭代。
递归或迭代方法的时间复杂度和空间复杂度均为O(N)
在实现遍历的方法中,Morris算法能将空间复杂度最优化达到O(1)。
Morris算法的实现规则:
记当前节点为cur
1)如果cur无左孩子,则cur向右移动(cur = cur.left)
2)如果cur有左孩子,则找到左孩子上的最右孩子,记为mostRight:
2.1)若mostRight的right为空,则让其指向cur,然后cur向左移动(cur = cur.left)
2.2)若mostRight的right = cur,则将指针right置空,且让cur向右移动(cur = cur.right)
以下为图解示例:
下面将用JAVA语言实现Morris算法的中序遍历:
使用例子:力扣:93.二叉树的中序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
TreeNode cur = root;
List<Integer> list = new ArrayList<>();
//Morris算法
while(cur != null){
//1、如果cur无左孩子,则cur向右移动(cur = cur.right)
if(cur.left == null){
list.add(cur.val);
cur = cur.right;
}
//2、如果cur有左孩子,则找到左孩子上的最右节点,记为mostRight
else if(cur.left != null){
TreeNode mostRight = cur.left;
while(mostRight.right != null && mostRight.right != cur){
mostRight = mostRight.right;
}
//2.1、如果mostRight的right为null,则让其指向当前节点cur,然后cur = cur.left
if(mostRight.right == null){
mostRight.right = cur;
cur = cur.left;
}else {//2.2、如果mostRight的right == cur,则将right置空,然后cur = cur.right
mostRight.right = null;
list.add(cur.val);
cur = cur.right;
}
}
}
return list;
}
}