这次练习主要是复习回溯法,之前一练主要还是学习了子集树与排序树的基本操作。

 

主要内容

  回顾知识:数字全排列(子集树、排序树)

  回溯法之加强版:素数环

  练习题:数字排序问题(蓝桥杯) + 39级台阶 + 数字排列(相邻之和为素数)

 


“温故而知新,可以为师矣“

 

全排列问题

【问题描述】

  给定数字n,请输出1~n的全部排列顺序。

  例如,n=3,输出:{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}

【题解】

  利用两种回溯法的代表解决该问题。

 

  子集树做法:借助 vis[ ] 来标记其在集合中的元素。

  构建搜索树,其每一层相当于排列中的每一个位置。

  用参数step控制当前位置

  该位置填入什么数字,还需看vis[ ]是否被标记过

  若该数字已被集合选中,不做处理,则找另外的数字

  若该数字未被选中,则把该位置赋值上该数字。同时进行下一层搜索。

  当到达叶子结点时,则进行回溯。

  回溯时别忘记把当前位置的数字撤标记。

  对于当前位置来说又可以填入另外的数字。

其核心代码:

for( int i = 1 ; i <= n ; i ++ ){
    if( vis[i] == 0 ){
        vis[i] = 1 ;    A[step] = i ;
        dfs_subset( step + 1 );
        vis[i] = 0 ;
    }
}

排列树做法:

  由于排列必须时n个数,别忘记要初始化数字,直接给赋上值。(1~n)

  然后进行排列树的常规操作。

  构建搜索树,其每一层相当于排列中的每一个位置。

  用参数<S,E>控制,S表示当前位置,E表示结束位置。

  我们所需要的是对下标为S,即当前位置的位置分别与后面的数字交换操作。

  其目的就是为达到该位置 把全部数字在该位置轮流打头。

  到达叶子结点的条件是,当前位置S已经是结束位置E

核心代码:

for( int i = S ; i <= E ; i++ ){
    swap( B[S] , B[i] );
    dfs_Permutation( S+1 , E );
    swap( B[S] , B[i] );
}

具体代码:

 

 1 //DFS 利用子集树 和 排列树 实现数字全排列
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N = 20 ;
 6 int vis[N],n;
 7  8 int A[N] , B[N];
 9 void dfs_subset(int step){
10     if( step == n ){
11         for( int i = 0 ; i < n ; i++ ){
12             printf("%3d",A[i]);
13         }
14         putchar('\n');
15     }
16     for( int i = 1 ; i <= n ; i ++ ){
17         if( vis[i] == 0 ){
18             vis[i] = 1 ;    A[step] = i ;
19             dfs_subset( step + 1 );
20             vis[i] = 0 ;
21         }
22     }
23 }
24 25 void dfs_Permutation( int S , int E ){
26     if( S == E ){
27         for( int i = 1 ; i <= n ; i++ ){
28             printf("%3d",B[i]);
29         }
30         putchar('\n');
31         return ;
32     }
33     for( int i = S ; i <= E ; i++ ){
34         swap( B[S] , B[i] );
35         dfs_Permutation( S+1 , E );
36         swap( B[S] , B[i] );
37     }
38 }
39 int main()
40 {
41     puts("Please input N :");
42     scanf("%d",&n);
43 44     puts(" dfs_subset tree");
45     dfs_subset(0);
46 47     puts(" dfs_Permutation tree");
48     for( int i = 1 ; i <= n ; i++ ){
49         B[i] = i ;
50     }
51     dfs_Permutation(1,n);
52     return 0;
53 }
全排列

相关文章:

  • 2021-11-23
  • 2021-08-06
  • 2021-12-25
  • 2021-12-18
  • 2022-01-15
  • 2021-04-02
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-02-03
相关资源
相似解决方案