1.Binary Tree Preorder Traversal
java:
使用栈,时间复杂度O(n),空间复杂度O(n)
public static void preOrderRec(Node root){
ArrayList<Integer> result = new ArrayList<>();
Stack<TreeNode> s = new Stack<>();
if (root != null) s.push(root);
while (!s.isEmpty()) {
final TreeNode p = s.pop();
result.add(p.val);
if (p.right != null) s.push(p.right);
if (p.left != null) s.push(p.left);
}
递归先序遍历,时间复杂度O(n),空间复杂度O(n)
public static void preOrderRec(Node root){
if(root!=null){
System.out.println(root.value);
preOrderRec(root.left);
preOrderRec(root.right);
}
}
pthon:
# 递归
def preorderTraversal(root):
if not root:
return
print(root.val)
dfs(root.left)
dfs(root.right)
# 栈
def preorderTraversal(root):
stack = [root]
while stack:
p = stack.pop()
print(p.val)
if p.right:
stack.append(p.right)
if p.left:
stack.append(p.left)
Morris先序遍历,时间复杂度O(n),空间复杂度O(1)
步骤:
1.如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。
2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。
a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。输出当前节点(在这里输出,这是与中序遍历唯一一点不同)。当前节点更新为当前节点的左孩子。
b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空。当前节点更新为当前节点的右孩子。
3.重复以上1、2直到当前节点为空。
public List<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
TreeNode cur = root;
TreeNode prev = null;
while (cur != null) {
if (cur.left == null) {
result.add(cur.val);
prev = cur;
cur = cur.right;
} else {
/* 查找前驱 */
prev = cur.left;
while (prev.right != null && prev.right != cur) {
prev = prev.right;
}
if (prev.right == null) { /* 还没线索化,则建立线索 */
result.add(cur.val); /* 仅这一行的位置与中序不同 */
prev.right = cur;
prev = cur; /* cur刚刚被访问过 */
cur = cur.left;
} else { /* 已经线索化,则访问节点,并删除线索 */
prev.right = null;
cur = cur.right;
}
}
}
return result;
}
2.Binary Tree Inorder Traversal
java:
使用栈,时间复杂度O(n),空间复杂度O(n)
public List<Integer> inorderTraversal(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
Stack<TreeNode> s = new Stack<>();
TreeNode pNode = root;
while (!s.isEmpty() || pNode != null) {
if (pNode != null) {
s.push(pNode);
pNode = pNode.left;
} else {
pNode = s.pop();
result.add(pNode.val);
pNode = pNode.right;
}
}
递归中序遍历,时间复杂度O(n),空间复杂度O(n)
public static void inOrderRec(Node root){
if(root!=null){
preOrderRec(root.left);
System.out.println(root.value);
preOrderRec(root.right);
}
}
python:
# 递归
def inorderTraversal(root):
if not root:
return
dfs(root.left)
print(root.val)
dfs(root.right)
# 栈
def inorderTraversal(root):
p = root
stack = []
while p or stack:
if p:
stack.append(p)
p = p.left
else:
cur = stack.pop()
print(cur.val)
p = cur.right
Morris先序遍历,时间复杂度O(n),空间复杂度O(1)
步骤:
1.如果当前节点的左孩子为空,则输出当前节点并将其右孩子作为当前节点。
2.如果当前节点的左孩子不为空,在当前节点的左子树中找到当前节点在中序遍历下的前驱节点。
a) 如果前驱节点的右孩子为空,将它的右孩子设置为当前节点。当前节点更新为当前节点的左孩子。
b) 如果前驱节点的右孩子为当前节点,将它的右孩子重新设为空(恢复树的形状)。输出当前节点。当前节点更新为当前节点的右孩子。
3.重复以上1、2直到当前节点为空。
public List<Integer> inorderTraversal1(TreeNode root) {
ArrayList<Integer> result = new ArrayList<>();
TreeNode cur = root;
TreeNode prev = null;
while (cur != null) {
if (cur.left == null) {
result.add(cur.val);
prev = cur;
cur = cur.right;
} else {
/* 查找前驱 */
prev = cur.left;
while (prev.right != null && prev.right != cur) {
prev = prev.right;
}
if (prev.right == null) {/* 还没线索化,则建立线索 */
prev.right = cur;
cur = cur.left;
} else {/* 已经线索化,则访问节点,并删除线索 */
result.add(cur.val);
prev.right = null;
prev = cur; /* cur刚刚被访问过 */
cur = cur.right;
}
}
}
return result;
}
3.Binary Tree Postorder Traversal
java:
使用栈,时间复杂度O(n),空间复杂度O(n)
/* p,正在访问的结点,q,刚刚访问过的结点 */
public static void postOrderRec(Node root){
TreeNode p = root.left;
Stack<TreeNode> s = new Stack<>();
s.push(root)
while (!s.isEmpty()) {
while (p != null) {
s.push(p);
p = p.left;
}
q = null;
while (!s.isEmpty()) {
p = s.pop();
if (p.right == q) {
result.add(p.val);
q = p;
} else {
s.push(p);
p = p.right;
break;
}
}
}
}
递归后序遍历,时间复杂度O(n),空间复杂度O(n)
public static void postOrderRec(Node root){
if(root!=null){
preOrderRec(root.left);
preOrderRec(root.right);
System.out.println(root.value);
}
}
python:
# 递归
def postorderTraversal(root):
if not root:
return
dfs(root.left)
dfs(root.right)
print(root.val)
# 栈
def postorderTraversal(root):
stack = [root]
p = root.left
while stack:
while p:
stack.append(p)
p = p.left
pre = None
while stack:
p = stack.pop()
if p.right == pre:
print(p.val)
pre = p
else:
stack.append(p)
p = p.right
break