深度优先遍历

对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次
深度优先遍历可以细分为:

  • 前序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树
  • 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树
  • 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根

具体实现方式可以分为:

  • 递归
  • 迭代

    广度优先遍历

    又叫层次遍历,从上往下对每一层依次访问,在每一层中,从左往右(或者从右往左)访问节点,访问完一层就进入下一层,直到没有节点可以访问为止

深度优先-递归实现前序、中序、后序遍历

  1. public void preOrder(TreeNode node) {
  2. if (node == null) {
  3. return;
  4. }
  5. System.out.print(node.val + " ");
  6. preOrder(node.left);
  7. preOrder(node.right);
  8. }
  1. public void inOrder(TreeNode node) {
  2. if (node == null) {
  3. return;
  4. }
  5. inOrder(node.left);
  6. System.out.print(node.val + " ");
  7. inOrder(node.right);
  8. }
  1. public void postOrder(TreeNode node) {
  2. if (node == null) {
  3. return;
  4. }
  5. postOrder(node.left);
  6. postOrder(node.right);
  7. System.out.print(node.val + " ");
  8. }

深度优先-递归实现前序、中序、后序遍历(返回结果)

  1. public ArrayList<Integer> preOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. preOrder(root, result);
  4. return result;
  5. }
  6. public void preOrder(TreeNode node, ArrayList<Integer> result) {
  7. if (node == null) {
  8. return;
  9. }
  10. result.add(node.val);
  11. preOrder(node.left, result);
  12. preOrder(node.right, result);
  13. }
  1. public ArrayList<Integer> inOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. inOrder(root, result);
  4. return result;
  5. }
  6. public void inOrder(TreeNode node, ArrayList<Integer> result) {
  7. if (node == null) {
  8. return;
  9. }
  10. preOrder(node.left, result);
  11. result.add(node.val);
  12. preOrder(node.right, result);
  13. }
  1. public ArrayList<Integer> postOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. postOrder(root, result);
  4. return result;
  5. }
  6. public void postOrder(TreeNode node, ArrayList<Integer> result) {
  7. if (node == null) {
  8. return;
  9. }
  10. preOrder(node.left, result);
  11. preOrder(node.right, result);
  12. result.add(node.val);
  13. }

深度优先-迭代实现遍历(返回结果)

迭代实现需要借助 Stack(栈),利用 Stack(栈)的 LIFO(后进先出)的特性辅助实现

  1. public ArrayList<Integer> deepOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. if (root == null) {
  4. return result;
  5. }
  6. Stack<TreeNode> stack = new Stack<>();
  7. // 将 root 节点放入栈
  8. stack.push(root);
  9. while (!stack.isEmpty()) {
  10. // 弹出栈顶元素
  11. TreeNode node = stack.pop();
  12. // 入栈顺序:先放左节点,后放右节点
  13. // 出栈顺序:先出右节点,后出左节点
  14. if (node.left != null) {
  15. // 放入弹出的栈顶元素的左子节点
  16. stack.push(node.left);
  17. }
  18. if (node.right != null) {
  19. // 放入弹出的栈顶元素的右子节点
  20. stack.push(node.right);
  21. }
  22. // 记录弹出的栈顶元素的值
  23. result.add(node.val);
  24. }
  25. return result;
  26. }
  1. public ArrayList<Integer> deepOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. if (root == null) {
  4. return result;
  5. }
  6. Stack<TreeNode> stack = new Stack<>();
  7. // 将 root 节点放入栈
  8. stack.push(root);
  9. while (!stack.isEmpty()) {
  10. // 弹出栈顶元素
  11. TreeNode node = stack.pop();
  12. // 入栈顺序:先放右节点,后放左节点
  13. // 出栈顺序:先出左节点,后出右节点
  14. if (node.right != null) {
  15. // 放入弹出的栈顶元素的右子节点
  16. stack.push(node.right);
  17. }
  18. if (node.left != null) {
  19. // 放入弹出的栈顶元素的左子节点
  20. stack.push(node.left);
  21. }
  22. // 记录弹出的栈顶元素的值
  23. result.add(node.val);
  24. }
  25. return result;
  26. }

深度优先-迭代实现前序、中序、后序遍历(返回结果)

假设有一棵树:

  1. 1
  2. / \
  3. 2 3
  4. / \ / \
  5. 4 5 6 7
  6. / \
  7. 8 9

广度优先-层次遍历(返回结果)

  1. public ArrayList<Integer> levelOrder(TreeNode root) {
  2. ArrayList<Integer> result = new ArrayList<>();
  3. if (root == null) {
  4. return result;
  5. }
  6. Queue<TreeNode> queue = new LinkedList<>();
  7. // 将 root 节点放入队列
  8. queue.offer(root);
  9. while (!queue.isEmpty()) {
  10. // 弹出队首元素
  11. TreeNode node = queue.poll();
  12. if (node.left != null) {
  13. // 放入弹出的队首元素的左子节点
  14. queue.offer(node.left);
  15. }
  16. if (node.right != null) {
  17. // 放入弹出的队首元素的右子节点
  18. queue.offer(node.right);
  19. }
  20. // 记录弹出的队首元素的值
  21. result.add(node.val);
  22. }
  23. return result;
  1. public class TreeNode {
  2. int val;
  3. TreeNode left;
  4. TreeNode right;
  5. TreeNode(){}
  6. TreeNode(int val) {this.val = val;}
  7. TreeNode(int val, TreeNode left, TreeNode right) {
  8. this.val = val;
  9. this.left = left;
  10. this.right = right;
  11. }
  12. }