众所周知,在二叉树的遍历方法中,最为常见的是递归,递归算法的时间复杂度与空间复杂度分别为O(n),O(n),而如果采用迭代方法,时间空间复杂度也相同。
但是如果数据量很大,而且呈单链排布,那么在递归或者迭代的过程中,栈的深度过大,可能会导致栈溢出的情况。
Morris遍历方法可以将空间复杂度降低到O(1)的程度,它的本质是线索化二叉树。
下文将以中序遍历为例。
首先模拟树节点
public class TreeNode(){
int val;
TreeNode left;
TreeNode right;
}
主体遍历
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> list=new ArrayList<>();
TreeNode pre=null;
while (root!=null){
//如果有左子节点,证明一定有前驱节点,寻找前驱节点。
if(root.left!=null){
//寻找前驱节点,即左子节点的最右子节点。
pre=root.left;
while (pre.right!=null&&pre.right!=root){
pre=pre.right;
}
//此时已经找到了前驱节点。
//如果右节点尚未进行线索化,那么进行线索化。
if(pre.right==null){
//线索化
pre.right=root;
//并对下一个左子节点进行线索化(进入下一个循环)
root=root.left;
}else { //如果前驱节点已进行了线索化,删除线索,处理后继节点。
pre.right=null;
list.add(root.val);
root=root.right;
}
}else { //如果没有左子节点,证明没有前驱节点,加入结果集,遍历后继节点。
list.add(root.val);
//值得注意的是,即使遍历到叶节点,也一定因为线索化有right节点。
root=root.right;
}
}
return list;
}
如有问题,欢迎讨论。