1、深度优先搜索(DFS)

顺序

image.png

剪枝

image.png

题目一

求n个数的所有排序
输入
3
输出
123
132
213
231
321
312

代码

  1. public class DFS {
  2. final static int N =100010;
  3. static int[] path = new int[N];
  4. static boolean[] st = new boolean[N];
  5. static int n;
  6. public static void main(String[] args) throws Exception {
  7. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  8. n = Integer.parseInt(br.readLine());
  9. dfs(0);
  10. }
  11. private static void dfs(int u) {
  12. if (u == n) {
  13. for (int i = 0; i < n; i++) System.out.print(path[i] + " ");
  14. System.out.println();
  15. return;
  16. }
  17. for (int i = 0; i < n; i++) { //递归
  18. if (!st[i]) {
  19. path[u] = i;
  20. st[i] = true;
  21. dfs(u+1);
  22. st[i] = false;
  23. }
  24. }
  25. }
  26. }

题目二

N-皇后问题

2、宽度优先搜索(BFS)

image.png

题目

给定一个nm的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。
最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。
数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。
输入格式
第一行包含两个整数n和m。
接下来n行,每行包含m个整数(0或1),表示完整的二维数组迷宫。
输出格式
输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围
1≤n,m≤100
输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
8
*代码展示

  1. public class Main {
  2. static int n,m;//记录地图大小
  3. static int[][] map = null;//记录地图
  4. static int[][] d = null;//记录走的距离
  5. public static void main(String[] args) throws Exception {
  6. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  7. String[] strs = br.readLine().split(" ");
  8. n = Integer.parseInt(strs[0]);
  9. m = Integer.parseInt(strs[1]);
  10. map = new int[n][m];
  11. d = new int[n][m];
  12. for (int i = 0; i < n; i++) {
  13. strs = br.readLine().split(" ");
  14. for (int j = 0; j < m; j++) {
  15. map[i][j] = Integer.parseInt(strs[j]);
  16. }
  17. }
  18. System.out.println(dfs());
  19. }
  20. private static int dfs() {
  21. Queue<Pair> q = new LinkedList<Pair>();
  22. /**
  23. * 判断上下左右是否符合规范
  24. */
  25. int[] dx = {1,0,-1,0},dy = {0,-1,0,1};
  26. q.offer(new Pair(0,0));
  27. while (!q.isEmpty()) {
  28. Pair p = q.poll();
  29. if (p.x == n-1 && p.y == m -1) break;
  30. for (int i = 0; i < 4; i++) {
  31. int x = p.x + dx[i];
  32. int y = p.y + dy[i];
  33. if (x >= 0 && x < n && y >=0 && y < m && d[x][y] == 0 && map[x][y] == 0) {
  34. q.offer(new Pair(x,y));
  35. d[x][y] = d[p.x][p.y] + 1;
  36. }
  37. }
  38. }
  39. return d[n-1][m-1];
  40. }
  41. }
  42. class Pair{
  43. public int x;
  44. public int y;
  45. public Pair(int x, int y) {
  46. this.x = x;
  47. this.y = y;
  48. }
  49. }

3、树与图的存储

image.png

4、树与图的深度优先遍历

题目

重心树

5、树与图的宽度优先遍历

题目

6、拓扑排序

image.png
image.png

题目