总结一下排列组合的算法问题

什么是全排列?

全排列(Full Permutation)。一般把1到n这n个整数按照某个顺序摆放的结果称为这n个数的一个排列,而全排列指这n个整数能形成的所有排列。

例如对1、2、3这三个整数来说

(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)就是一个全排列。

  那么如何解决这类全排列问题?,从递归的角度去考虑,如果把问题描述成“输出1到n个整数的全排列”,那么它就可以被分为若干个子问题:

“输出以1开头的全排列”“输出以2为开头的全排列”……“输出以n为开头的全排列”。不妨设定一个数组P,用来存放当前的排列;再设定一

个散列数组hashTable,其中hashTable[x]当整数x已经在数组P中时为true。(毕竟全排列中的一个排列每一项只用一次)。

  现在按顺序往P的第一位到第n位中填入数字。不妨假设当前已经填好了P[1]到P[index-1],正准备填P[index]。显然需要枚举1到n,如果

当前数字x还没有在P[1]到P[index-1]中(即hashTable[x]==false),那么就把它填入P[index],同时将hashTable[x]置为true,然后去处理第

index+1位(即进行递归);而当递归完成时,再将hashTable[x]还原位false,以便让P[index]填下一个数字。

 

我简单的画了一下数组图,如下:

 

 

 代码如下:

 1 #include <stdio.h>
 2 
 3 
 4 void generateP(int index);  
 5 
 6 const int maxn = 11;
 7 
 8 int n;
 9 int P[maxn],hashTable[maxn]={0};
10 int main(){
11     
12     int array[3] = {1,2,3};
13     
14     n = 3;
15     
16     //从当前处理排列的第0号开始 
17     generateP(1); 
18     return 0;
19 } 
20 
21 
22 void generateP(int index){
23     
24     if(index == n+1){
25         for(int i = 1;i<=n;i++){
26             printf("%d ",P[i]);
27         }
28         printf("\n");
29         //return;
30     } 
31     
32     //递归体
33     for(int x = 1;x <=n;x++){//枚举1到n,试图将x填入P[index] 
34         if(hashTable[x]==0){//如果x不在P[0]到P[index-1]中
35             P[index] = x;    //令P的第index位为x,即把x加入当前排列 
36             hashTable[x] = 1; //记录x已经在P中了(不能再利用) 
37             generateP(index+1);    //处理排列的第index+1号位
38             hashTable[x] = 0;     //已经处理完P[index]为x的子问题了,还原状态 
39         }
40     } 
41 }

可以看到输出结果如下:

 

 

这个和我们之前的思路是一致的。即从递归的角度去考虑,“输出以1开头的全排列”、“输出以2开头的全排列”、“输出以3开头的全排列”。

另一种写法

 

 

 1 #include <stdio.h>
 2 
 3 
 4 
 5 
 6 void swap(int A[],int i,int j);
 7 void printArray(int A[],int n);
 8 void perm(int A[],int p,int q);
 9 
10 int main(){
11     
12     int A[3] = {1,2,3};
13     perm(A,0,3);
14     
15     return 0;
16 }
17 
18 void swap(int A[],int i,int j){
19     int temp = A[i];
20     A[i] = A[j];
21     A[j] = temp;
22 }
23 
24 void printArray(int A[],int n){
25     for(int i = 0;i < n;i++){
26         printf("%d ",A[i]);
27     }
28     printf("\n");
29 }
30 
31 void perm(int A[],int p,int q){
32     if(p == q){
33         printArray(A,q);
34     }
35     
36     for(int i = p;i <q;i++){
37         swap(A,p,i);
38         perm(A,p+1,q);
39         swap(A,p,i);  
40     }
41 }

 

posted @ 2020-03-22 21:48  focusDing  阅读(579)  评论(0编辑  收藏  举报