Morris 遍历
- Morris 遍历改写成后序遍历
- 解题思路
- 代码演示
- Morris 遍历
Morris 遍历改写成后序遍历
通过Morris遍历的顺序,将其调整为后序遍历的顺序,
解题思路
不明白morris 遍历,先查看上期
遍历二叉树的神级方法–Morris遍历
morris 遍历改写前序遍历和中序遍历都很简单,改写后序遍历是比较麻烦的,
1.需要在第二次到左树最后节点时,将当前节点的左树和左树的所有右子树,进行逆序输出,这里就需要指针的重连操作了,需要很细心,不要连错了,逆序输出后,还要将指针恢复,
2.在morris 遍历结束后,单独对头节点进行逆序其右节点。输出右节点的值。
示例:
后序遍历结果是:4 5 2 6 7 3 1.
在morris 遍历中,最开始节点在1节点,在遍历的过程中,节点不断向左子树移动,当第一次,节点的左子树的右节点不是null 时,cur 来到了2 节点,我们对2 节点的所有左子树和左子树的右节点进行逆序输出,
就先输出了4 :
再次回到1节点时,1节点的最右子节点5 的右子树不为null.将1节点的左子树和左子树上所有的右子树逆序输出,也就是2 -> 5 ,逆序,5 2 输出,
…
代码演示
public static class Node{
int val;
Node left;
Node right;
public Node(int val) {
this.val = val;
}
}
/**
* 后序遍历
* @param root
*/
public static void morrisPos(Node root){
if (root == null){
return;
}
//当前遍历到的节点
Node cur = root;
//当前节点的左树左右节点
Node mostRight = null;
while (cur != null){
//先拿住当前节点的左子树
mostRight = cur.left;
//左子树不为null 时。进行左子树上的重连和找到最右节点的操作
if (mostRight != null){
//找到左子树的最右接点
while (mostRight.right != null && mostRight.right != cur){
mostRight = mostRight.right;
}
//第一次来到最右节点时,进行下面操作
if (mostRight.right == null){
mostRight.right = cur;
cur = cur.left;
continue;
}else {
//第二次来到这个最右节点时,恢复指针。
mostRight.right = null;
printEdge(cur.left);
}
}
//左子树为null 时,去右子树遍历
cur = cur.right;
}
printEdge(root);
}
/**
* 当前节点顺序先调成逆序,然后输出节点值
* 最后再把顺序调整过来
* @param root
*/
public static void printEdge(Node root){
Node tail = reverseEdge(root);
Node cur = tail;
while (cur != null){
System.out.print(cur.val+ " ");
cur = cur.right;
}
reverseEdge(tail);
}
/**
* 当前节点的后序节点进行逆序
* @param root
*/
public static Node reverseEdge(Node root){
Node pre = null;
Node next = null;
while (root != null){
next = root.right;
root.right = pre;
pre = root;
root = next;
}
return pre;
}
Morris 遍历
遍历二叉树的神级方法–Morris遍历
二叉树Morris遍历改写成前序遍历和中序遍历