二叉树的深度优先遍历
- 前序遍历:先访问当前节点,再依次递归访问左右子树
- 中序遍历:先递归访问左子树,再访问自身,再递归访问右子树
- 后续遍历:先递归访问左右子树,再访问自身节点
前序:
private void preOrder(Node node){ if(node == null) return; visit(node); preOrder(node.left); preOrder(node.right); }
private void preOrderByStack(Node p){ if(p == null) return; Stack<Node> stack = new Stack<Node>(); stack.push(p); while(!stack.isEmpty()){ p = stack.pop(); visit(p); if(p.right != null) stack.push(p.right); if(p.left != null) stack.push(p.left); } }
中序:
private void inOrderByStack(Node p){ if(p == null) return; Stack<Node> stack = new Stack<Node>(); while(!stack.isEmpty() || p != null){ while(p != null){ stack.push(p); p = p.left; } if(!stack.isEmpty()){ p = stack.pop(); visit(p); p = p.right; } } }
后序:
private void postOrderByStack(Node p){ if(p == null) return; Stack<Node> stack = new Stack<Node>(); Node q = null; while(p != null){ stack.push(p); p = p.left; } while(!stack.isEmpty()){ p = stack.pop(); if(p.right != null && p.right != q){ stack.push(p); p = p.right; while(p != null){ stack.push(p); p = p.left; } }else { visit(p); q = p; } } }
广度遍历:
private void levelOrder(Node p){ if(p == null) return; Queue<Node> q = new LinkedList<Node>(); q.offer(p); while(!q.isEmpty()){ Node node = q.poll(); visit(node); if(node.left != null) q.offer(node.left); if(node.right != null) q.offer(node.right); } }
深度(递归):
private int getDepth(Node node){ if(node == null) return 0; int left = getDepth(node.left); int right = getDepth(node.right); return left > right ? left + 1 : right + 1; }
广度和深度优先遍历:
两者都很高效为O(n),基本是最小的,因为每个点至少要遍历一次~
之前的快速排序和归并排序,两者的本质上都是二叉树的深度优先遍历过程。