- 前序遍历:
1.根节点为空,直接返回
2.用cur标记当前结点
3.cur或栈不为空时:若当前结点不为空,打印,并进栈,一直走到最左边
3.cur或栈不为空时:若当前结点为空,栈顶元素出栈,让cur指向其右孩子
public void preorderTraversal(TreeNode root) {
if(root == null)
return;
System.out.print(root.val);
preorderTraversal(root.left);
preorderTraversal(root.right);
}
public void preorderTraversal2(TreeNode root) {
if(root == null)
return;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
while(cur != null){
System.out.print(cur.val);
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.pop();
cur = top.right;
}
}
- 中序遍历:
1.根节点为空,直接返回
2.用cur标记当前结点
3.cur或栈不为空时:若当前结点不为空,直接进栈,一直走到最左边
3.cur或栈不为空时:若当前结点为空,栈顶元素出栈,并打印,然后让cur指向其右孩子
public void inorderTraversal(TreeNode root) {
if(root == null)
return;
inorderTraversal(root.left);
System.out.print(root.val);
inorderTraversal(root.right);
}
public void inorderTraversal2(TreeNode root) {
if(root == null)
return;
TreeNode cur = root;
Stack<TreeNode> stack = new Stack<TreeNode>();
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
TreeNode top = stack.pop();
System.out.print(top.val);
cur = top.right;
}
}
- 后序遍历:
1.根节点为空,直接返回
2.用cur标记当前结点,用prev标记已访问过的结点
3.cur或栈不为空时:若当前结点不为空,直接进栈,一直走到最左边
3.cur或栈不为空时:若当前结点为空,取栈顶元素,若该元素的右孩子为空或已被访问,则栈顶元素出栈并打印,同时更新prev和cur
4.cur或栈不为空时:若该元素的右孩子不为空或没有被访问,则让cur指向其右孩子
public void postorderTraversal(TreeNode root) {
if(root == null)
return;
postorderTraversal(root.left);
postorderTraversal(root.right);
System.out.print(root.val);
}
public void postorderTraversal2(TreeNode root) {
if(root == null)
return;
TreeNode cur = root;
TreeNode prev = null;
Stack<TreeNode> stack = new Stack<TreeNode>();
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.peek();
if(cur.right == null || cur.right==prev){
System.out.print(cur.val);
stack.pop();
prev = cur;
cur = null;
}
else{
cur = cur.right;
}
}
}