DFS与BFS怎么写代码:

1)二叉树的DFS怎么写代码:

1、先左递归、再右递归;
2、遇到叶子节点,(递归触底),直接回溯;
3、当前节点的左递归、右递归函数都调用结束之后,还是要回溯一级;
代码示范:

  1. public static boolean DFSHelper(TreeNode node,...其他参数) {
  2. TreeNode leftNode = node.left;
  3. TreeNode rightNode = node.right;
  4. //...其他代码
  5. //如果当前节点不是叶子结点:
  6. if (leftNode != null || rightNode != null) {
  7. //继续递归该节点的左右子节点:
  8. methodHelper(leftNode, ...其他参数); //先左递归
  9. methodHelper(rightNode, ...其他参数); //再右递归
  10. }
  11. //如果当前节点是叶子结点:
  12. else{
  13. //...其他代码
  14. // 递归到底了,回溯
  15. return;
  16. }
  17. return;
  18. }

代码示范:DFS深度优先遍历-记录节点路径

  1. /**
  2. * DFS深度优先遍历,寻找某个节点,并记录从根结点到该节点的路径:
  3. * @param root
  4. * @param targetNode 目标节点
  5. * @param deque 记录路径
  6. * @return
  7. */
  8. public static boolean dfs(TreeNode root, TreeNode targetNode, Deque<TreeNode> deque) {
  9. //base case
  10. if (root == null) {
  11. return false;
  12. }else{
  13. deque.push(root);
  14. if (root == targetNode) {
  15. return true;
  16. }
  17. TreeNode leftNode = root.left; //左子结点
  18. TreeNode rightNode = root.right; //右子节点
  19. //非叶子节点
  20. if (leftNode != null || rightNode != null) {
  21. //DFS,先左递归,再右递归,然后左递归、右递归都结束之后,回溯一级;
  22. if (leftNode != null) {
  23. boolean b = dfs(leftNode, targetNode, deque);
  24. //如果递归过程中,找到了目标节点,则直接返回true,不必再递归其他地方了;
  25. if (b) {
  26. return b;
  27. }
  28. }
  29. if (rightNode != null) {
  30. boolean b = dfs(rightNode, targetNode, deque);
  31. //如果递归过程中,找到了目标节点,则直接返回true,不必再递归其他地方了;
  32. if (b) {
  33. return b;
  34. }
  35. }
  36. }
  37. //叶子结点,直接return,回溯一级:
  38. //负责记录路径的集合,也要相应撤销选择:
  39. else{
  40. deque.pop();
  41. return false;
  42. }
  43. }
  44. //左递归、右递归都结束之后,回溯一级;
  45. //负责记录路径的集合,也要相应撤销选择:
  46. deque.pop();
  47. return false;
  48. }

2)非树结构的DFS怎么写代码:

非树结构的DFS与二叉树的DFS原理是一样的,唯一不同的是二叉树的DFS涉及到对左子树的左递归和右子树的右递归,而非树结构没有子树的概念
所以非树结构是直接递归下一级元素,递归触底之后直接回溯一级,以及每一个递归函数调用结束之后,都要回溯一级

代码流程:
1、先递归遍历该元素的下一级;
2、如果遇到最后一个元素,(递归触底),直接回溯;
3、当前元素的递归函数调用结束之后,也是记得要回溯一级;

代码示例:全排列问题:

  1. /**
  2. * 全排列问题:
  3. * 思路:把nums中的每个元素,抽象成以该节点为根节点的多叉树,DFS该多叉树,记录路径
  4. * 最终所有的路径的组合就是result;
  5. *
  6. * @param nums
  7. * @return
  8. */
  9. public static List<List<Integer>> permute(int[] nums) {
  10. List<List<Integer>> result = new ArrayList<>();
  11. LinkedList<Integer> list = new LinkedList<>();
  12. for (int root : nums) {
  13. list.clear();
  14. list.add(root);
  15. dfs(root, nums, list, result);
  16. }
  17. System.out.println("result = " + result);
  18. return result;
  19. }

dfs:全排列问题——非树结构

  1. /**
  2. * 将数组中每个元素抽象为:以其为根节点的多叉树,当然这里没有子树的概念
  3. * DFS深度优先遍历以数组中每个元素为根节点的多叉树,记录路径;
  4. * @param deque
  5. */
  6. public static void dfs(int root, int[] nums, LinkedList<Integer> deque, List<List<Integer>> result) {
  7. for (int num : nums) {
  8. if (num == root) {
  9. continue;
  10. }
  11. if (!deque.contains(num)) {
  12. deque.add(num);
  13. //如果是最后一个元素,递归触底,然后"路径记录"回溯一级:
  14. if (deque.size() == nums.length) {
  15. //递归已经触底,将其记录下来:
  16. result.add(new LinkedList<>(deque));
  17. deque.pollLast(); //"路径记录"回溯一级
  18. return;
  19. }
  20. //如果没有触底,当前元素的递归函数调用结束之后,也是要记得将"路径记录"回溯一级;
  21. else {
  22. dfs(root, nums, deque, result);
  23. //递归结束之后,"路径记录"回溯一级;
  24. deque.pollLast();
  25. }
  26. } else {
  27. continue;
  28. }
  29. }
  30. return;
  31. }


3)二叉树的BFS怎么写代码:

  • BFS函数的声明中,用一个队列参数作为辅助数据结构
  • 先将队列中的节点出队列,然后从左到右将该节点的子节点都加入到队列,
  • 直到队列为空;

代码示例:

  1. public static void BFSHelper(Queue<TreeNode> queue,其他参数) {
  2. while (!queue.isEmpty()) {
  3. TreeNode headNode = queue.poll(); //头结点
  4. TreeNode leftNode = headNode.left;
  5. TreeNode rightNode = headNode.right;
  6. //如果为非叶子节点:
  7. if (leftNode != null) {
  8. queue.offer(leftNode);
  9. }else if(rightNode != null){
  10. queue.offer(rightNode);
  11. }
  12. //如果为叶子结点:
  13. else{
  14. continue;
  15. }
  16. }
  17. return;
  18. }