二叉树——线索化遍历
1. Morris遍历
1.1. 思路
Morris遍历通过利用左子树前序遍历下的最后一个节点的right指针,来做到以时间复杂度为O(n)空间复杂度为O(1)的开销遍历一个二叉树。
1.2. 代码
public static <T> void morrisPre(TreeNode<T> root, Consumer<T> consumer) {
TreeNode<T> cur = root;
while (cur != null) {
if (cur.left != null) {
TreeNode<T> leftLast = cur.left;
while (leftLast.right != null && leftLast.right != cur)
leftLast = leftLast.right;
if (leftLast.right == null) {
leftLast.right = cur;
} else {
leftLast.right = null;
cur = cur.right;
continue;
}
}
consumer.accept(cur.val);
cur = cur.left != null ? cur.left : cur.right;
}
}
public static <T> void morrisMid(TreeNode<T> root, Consumer<T> consumer) {
TreeNode<T> cur = root;
while (cur != null) {
if (cur.left != null) {
TreeNode<T> leftLast = cur.left;
while (leftLast.right != null && leftLast.right != cur) {
leftLast = leftLast.right;
}
if (leftLast.right == null) {
leftLast.right = cur;
cur = cur.left;
continue;
} else {
leftLast.right = null;
}
}
consumer.accept(cur.val);
cur = cur.right;
}
}
public static <T> void morrisPost(TreeNode<T> root, Consumer<T> consumer) {
TreeNode<T> cur = root;
while (cur != null) {
if (cur.left != null) {
TreeNode<T> leftLast = cur.left;
while (leftLast.right != null && leftLast.right != cur) {
leftLast = leftLast.right;
}
if (leftLast.right == null) {
leftLast.right = cur;
} else {
leftLast.right = null;
consumeRightBound(cur.left, consumer);
cur = cur.right;
continue;
}
}
cur = cur.left != null ? cur.left : cur.right;
}
consumeRightBound(root, consumer);
}
private static <T> void consumeRightBound(TreeNode<T> node, Consumer<T> consumer) {
TreeNode<T> pre = null;
TreeNode<T> cur = node;
TreeNode<T> next;
while (cur != null) {
next = cur.right;
cur.right = pre;
pre = cur;
cur = next;
}
cur = pre;
pre = null;
while (cur != null) {
consumer.accept(cur.val);
next = cur.right;
cur.right = pre;
pre = cur;
cur = next;
}
}
作者: 迈吉
出处: https://www.cnblogs.com/stepfortune/
关于作者:迈吉
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(showable@qq.com)咨询.