二叉树遍历 - l00jj/algorithm GitHub Wiki
官方解
大一统辅佐标记法
存放时增加一个维度记录当前状态,前中后都可以适用,只需要改变标记点即可,主体思路是模拟递归,而递归存在状态,用另外一个维度存放这个状态;
# 中序
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
WHITE, GRAY = 0, 1
res = []
stack = [(WHITE, root)]
while stack:
color, node = stack.pop()
if node is None: continue
if color == WHITE:
stack.append((WHITE, node.right))
stack.append((GRAY, node)) # 调整其位置即可,中间就是中序,放前头就是后序,放后面就是前序
stack.append((WHITE, node.left))
else:
res.append(node.val)
return res
实际上是对这个的一种模拟
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
res = []
def dfs(node):
if not node: return
dfs(node.left)
res.append(node.val) # 调整其位置即可,中间就是中序,放前头就是前序,放后面就是后序
dfs(node.right)
dfs(root)
return res
标准前序遍历
可以翻转过程变成后序
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
res = []
if not root: return res
stack = []
while stack or root:
while root:
res.append(root.val)
stack.append(root)
root = root.left
root = stack.pop()
root = root.right
return res
Morris
中序遍历
var inorderTraversal = function(root) {
const res = [];
let predecessor = null;
while (root) {
if (root.left) {
// predecessor 节点就是当前 root 节点向左走一步,然后一直向右走至无法走为止
predecessor = root.left;
while (predecessor.right && predecessor.right !== root) {
predecessor = predecessor.right;
}
// 让 predecessor 的右指针指向 root,继续遍历左子树
if (!predecessor.right) {
predecessor.right = root;
root = root.left;
}
// 说明左子树已经访问完了,我们需要断开链接
else {
res.push(root.val);
predecessor.right = null;
root = root.right;
}
}
// 如果没有左孩子,则直接访问右孩子
else {
res.push(root.val);
root = root.right;
}
}
return res;
};
前序遍历
class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]:
res = list()
if not root:
return res
p1 = root
while p1:
p2 = p1.left
if p2:
while p2.right and p2.right != p1:
p2 = p2.right
if not p2.right:
res.append(p1.val)
p2.right = p1
p1 = p1.left
continue
else:
p2.right = None
else:
res.append(p1.val)
p1 = p1.right
return res
后序遍历
class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]:
def addPath(node: TreeNode):
count = 0
while node:
count += 1
res.append(node.val)
node = node.right
i, j = len(res) - count, len(res) - 1
while i < j:
res[i], res[j] = res[j], res[i]
i += 1
j -= 1
if not root:
return list()
res = list()
p1 = root
while p1:
p2 = p1.left
if p2:
while p2.right and p2.right != p1:
p2 = p2.right
if not p2.right:
p2.right = p1
p1 = p1.left
continue
else:
p2.right = None
addPath(p1.left)
p1 = p1.right
addPath(root)
return res