Morris遍历是实现了时间复杂度O(N),空间复杂度只有O(1)的二叉树遍历的一种方法,它实现的方法主要为每个节点只遍历一次,具体规则如下:
- cur当前节点如果左子树为空,则向右移动 (cur = cur.right)
- cur当前节点左子树不为空,则找到左子树中最右的节点记为Tr,若
- Tr右节点为空,则让Tr右节点指向粗人,同时cur左移 (cur = cur.left)
- Tr右节点指向cur,cur右移 (cur = cur.right)
个人感觉Morris的本质就是将原先的单向遍历加入了回溯,即有左子树的节点在遍历完左子树后还可以再返回该节点,并向右继续遍历,也即实现了有左子树的节点只遍历2次,无左子树的节点只遍历一次。
附上一点别人的代码:
前序遍历
public static void morrisPre(Node head) {
if(head == null){
return;
}
Node cur = head;
Node mostRight = null;
while (cur != null){
mostRight = cur.left;
if(mostRight != null){
while (mostRight.right !=null && mostRight.right != cur){
mostRight = mostRight.right;
}
if(mostRight.right == null){
mostRight.right = cur;
System.out.print(cur.value+" ");
cur = cur.left;
continue;
}else {
mostRight.right = null;
}
}else {
System.out.print(cur.value + " ");
}
cur = cur.right;
}
System.out.println();
}
引用自https://zhuanlan.zhihu.com/p/101321696