/* 排列问题: 有n个元素,编号为1,2,…,n,用一个具有n个元素的数组A来 存放所生成的排列, 然后输出它们。 自己分析: 关于全排列生成问题,刘汝佳介绍的算法的主体思路。 首先我们需要确定第一个数,这个数的选取是;遍历A[1]~A[n] 接下来如何选取第二个数,这是一个问题: 采用的方法是:判断当前位置上是不是已经有元素,如果没有就紧接着填充第2个元素 算法出口是:当标记变量为0的时候,那么n个元素全部填充完毕,此时输出所有组合 刘汝佳算法思想: 遍历所有的数,判断当前元素与前面元素不能重复,统计A[0]~A[iPos-1]中 当前待选取元素A[i]出现的次数c1,统计 A[0]~A[n-1]中A[i]出现的总次数c,如果c1<c是可以重复出现的 设置Per[pos] = A[i]并进行下面的递归 输入: 3 1 2 3 输出: 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 */ /* 关键: 1 遍历所有的数,判断当前元素与前面元素不能重复,统计A[0]~A[iPos-1]中 当前待选取元素A[i]出现的次数c1,统计 A[0]~A[n-1]中A[i]出现的总次数c,如果c1<c是可以重复出现的 设置Per[pos] = A[i]并进行下面的递归 2 for(int i = 0 ; i < iLen ; i++)//对每个元素进行遍历尝试是否可以放入到最终数组中 { if(!i || pArr[i] != pArr[i-1])//解决重复输出,这里采用或 { int c1 = 0; for(int k = 0 ; k < iDepth ;k++)//统计在待插入元素在现有数组中出现的次数 { if(pArr[i] == pPermutationArr[k]) { c1++; } } int c = 0; for(int m = 0 ; m < iLen ;m++)//统计待插入元素在原始数组中出现的次数 { if(pArr[i] == pArr[m]) { c++; } } if(c1 < c)//如果还没有超出次数,则可以放入 { pPermutationArr[iDepth] = pArr[i]; dfs(pArr,iLen,pPermutationArr,iDepth+1); 3 void dfs(int* pArr,int iLen,int* pPermutationArr,int iDepth) 4 交换法思想 //对每个元素递归 for(int i = iPos ; i < iLen ; i++) { //采用交换的方法:第一个元素与第二个元素交换 int iTemp = pArr[i]; pArr[i] = pArr[iPos]; pArr[iPos] = iTemp; permutation(pArr,iLen,iPos+1);//继续递归从iPos后面继续进行交换 //回溯 iTemp = pArr[i]; pArr[i] = pArr[iPos]; pArr[iPos] = iTemp; */ #include <stdio.h> #include <string.h> const int MAXSIZE = 10000; int g_visArr[MAXSIZE]; void dfs(int* pArr,int iLen,int* pPermutationArr,int iDepth) { if(!pArr || iLen < 0)//鲁棒性 { return ; } if(iDepth == iLen)//递归出口 { for(int i = 0 ; i < iLen ; i++) { if(i) { printf(" %d",pPermutationArr[i]); } else { printf("%d",pPermutationArr[i]); } } printf("\n"); return;//这里还需要返回 } for(int i = 0 ; i < iLen ; i++)//对每个元素进行遍历尝试是否可以放入到最终数组中 { if(!i || pArr[i] != pArr[i-1])//解决重复输出,这里采用或 { int c1 = 0; for(int k = 0 ; k < iDepth ;k++)//统计在待插入元素在现有数组中出现的次数 { if(pArr[i] == pPermutationArr[k]) { c1++; } } int c = 0; for(int m = 0 ; m < iLen ;m++)//统计待插入元素在原始数组中出现的次数 { if(pArr[i] == pArr[m]) { c++; } } if(c1 < c)//如果还没有超出次数,则可以放入 { pPermutationArr[iDepth] = pArr[i]; dfs(pArr,iLen,pPermutationArr,iDepth+1); } } } } void permutation(int* pArr,int iLen,int iPos) { if(iPos == iLen) { for(int i = 0 ; i < iLen ; i++) { if(i) { printf(" %d",pArr[i]); } else { printf("%d",pArr[i]); } } printf("\n"); return; } //对每个元素递归 for(int i = iPos ; i < iLen ; i++) { //采用交换的方法:第一个元素与第二个元素交换 int iTemp = pArr[i]; pArr[i] = pArr[iPos]; pArr[iPos] = iTemp; permutation(pArr,iLen,iPos+1);//继续递归从iPos后面继续进行交换 //回溯 iTemp = pArr[i]; pArr[i] = pArr[iPos]; pArr[iPos] = iTemp; } } void process() { int n; int iArr[MAXSIZE]; int iPermutationArr[MAXSIZE];//用于存放生成的排列 while(EOF != scanf("%d",&n)) { if(n <= 0) { break; } for(int i = 0 ; i < n ; i++) { scanf("%d",&iArr[i]); } memset(g_visArr,0,sizeof(g_visArr)); //dfs(iArr,n,iPermutationArr,0); //printf("\n"); permutation(iArr,n,0); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }