每一个递归都可以画一个树,借树图来理解

image.png
2^3 = 8 (共8个结果)
因为有两个分支(选或者不选),所以要写两个递归。
几叉树就写几个递归,想想一下我们在方法里面写两个递归,传参是层数,那么调用的时候,每一层只要进方法,就会生成两种递归,就像二叉树一样。
boolean用来对应位数,因为数字固定所以for循环固定,每一位上的数也是固定的,比如在1层(位)我选不选1,也就是选不选布尔值索引1
位数=层数=i=布尔值索引

  1. package lanqiaobei.recursion;
  2. import java.util.Scanner;
  3. public class ExponentialNum {
  4. static int bound;
  5. static boolean[] booleans = new boolean[20];
  6. static void dfs(int u){
  7. if (u > bound){
  8. for (int i = 1 ;i <= bound ;i++) {
  9. if (booleans[i]){
  10. System.out.print(i);
  11. }
  12. }
  13. System.out.println();
  14. return;
  15. }
  16. booleans[u] = false;
  17. dfs(u+1);
  18. booleans[u] = true;
  19. dfs(u+1);
  20. }
  21. public static void main(String[] args) {
  22. Scanner scanner = new Scanner(System.in);
  23. bound = scanner.nextInt();
  24. dfs(1);
  25. }
  26. }

排列数字 VS 指数型枚举

排列数字

排列数字线程是单线程,也就是一个线程递归结束以后,才会按树的结构往回走(线程往回回收执行),继续下一个递归任务,所以它打印的顺序是从左往右,从上往下的。

指数型枚举

指数型枚举的线程是双线程,并且每一层都会指数型裂变出线程(所以打印顺序谁先谁都都不一定),最后return回收线程代表该线程任务结束。每个线程是独立的异步的,独立要强调一下,每个递归线程里它是否设置某个值为true或者false,线程之间不会互相感染,是独立!

指数型枚举核心

二叉树,所以两个递归线程(每次递归进入下一层,都分两个递归线程;这样线程的分离就和树结构一样)
布尔值数组让索引等同于我们的数字,而索引对应的true和false代表我们是否选中,同时用循环来让布尔数组不越界判断。

细分析运行

代码是有优先级别的,如果我们把不选这个递归放在前面,不选的优先级>选的优先级。那么它的打印顺序就是从右向左,从上到下的。