排列组合生成算法之字典序法和换位法动画ppt
- 格式:pptx
- 大小:52.89 MB
- 文档页数:50
算法之字典排序法2. 字典序法字典序法就是按照字典排序的思想逐一产生所有排列.设想要得到由1,2,3,4以各种可能次序产生出4!个“单词”. 肯定先排1234, 再排1243, 下来是1324, 1342, …., 4321.分析这种过程, 看如何由一个排列得到下一个排列, 并给出严格的数学描述.例2.3 设有排列(p) =2763541, 按照字典式排序, 它的下一个排列是?(q) =2764135.(1) 2763541 [找最后一个正序35](2) 2763541 [找3后面比3大的最后一个数](3) 2764531 [交换3,4的位置](4) 2764135 [把4后面的531反序排列为135即得到最后的排列(q)]求(p)=p1⋯p i-1p i…p n的下一个排列(q):(1) 求i=max{j⎪ p j-1<p j}(找最后一个正序)(2) 求j=max{k⎪ p i-1<p k}(找最后大于p i-1者)(3) 互换p i-1与p j得p1…p i-2 p j p i p i+1⋯p j-1 p i-1 p j+1…p n(4) 反排p j后面的数得到(q):p1…p i-2 p j p n⋯p j+1p i-1p j-1 ….p i+1 p i例2.4 设S={1,2,3,4}, 用字典序法求出S的全部排列. 解1234, 1243, 1324, 1342, 1423, 1432,2134, 2143, 2314, 2341, 2413, 2431,3124, 3142, 3214, 3241, 3412, 3421,4123, 4132, 4213, 4231, 4312, 4321.字典排序法C++代码:#include<iostream.h>void repailie(int *a,int n,int dp){int *bb=new int[n-dp];int *cc=new int[n-dp];int ti=0;for(int i=dp+1;i<n;i++){bb[ti++]=a[i];}for(int j=0;j<ti;j++){a[j+dp+1]=bb[ti-j-1];}//cout<<a[dp+1]<<" ";//cout<<endl;}int main(void){int n;cout<<"请输入1至无穷大的数"<<endl;cin>>n;int *a=new int[n];int p=1;//n的阶层int q=1;//循环记录int b,c;//最后一对正序int bi,ci;//记录b和c的位置int d;//最后大于b者int di;//记录d的位置for (int o=1;o<=n;o++){p=p*o;//cout<<p<<" ";}for (int i=0;i<n;i++){a[i]=i+1;cout<<a[i]<<" ";}cout<<endl;while(q<p){for(int j=n-1;j>=0;j--){if(a[j-1]<a[j]){b=a[j-1];bi=j-1;c=a[j];ci=j;break;}}//cout<<bi<<" "<<ci<<" "<<endl;for(int k=n-1;k>=0;k--)if (a[k]>b){d=a[k];di=k;break;}}//cout<<di<<endl;for(int l=0;l<n;l++){if(l==di){a[l]=b;//cout<<a[l]<<endl;}if(l==bi){a[l]=d;//cout<<a[l]<<endl;}repailie(a,n,bi);for (int m=0;m<n;m++){cout<<a[m]<<" ";}cout<<endl;++q;}}运行结果图:。