字典序法中,對數字一、二、3.....n的排列的前後關係是從左到右逐個比較對應的數字的前後來決定的。例如對於5個數字的排列12345和12354,排列12345在前,排列12354在後面。按照這樣的規定,5個數字的全部排列中最前面的是12345,最後面的是54321. 算法
字典序算法以下: spa
設P是1~n的一個全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn 3d
1)從排列的右端開始,找出第一個比右邊數字小的數字的序號j(j從左端開始計算),即j=max{i|pi<pi+1} code
2)在pj的右邊數字中,找到全部比pj大的數字中最小的數字pk 排序
3)對換pj,pk input
4)再將pj+1....pk-1pkpk+1pn逆轉獲得排列p'=p1p2...pj-1pjpn...pk+1pkpk-1...pj+1,這就是排列p的下一個排列。 io
例如21379854是數字1~9的一個排列。從它生成下一個排列的步驟以下: class
1)「自右至左」找出排列中第一個比右邊數字小的數字:7 循環
2)在該數字後的數字中找到比7大的數中最小的一個:8 sort
3)將7和8交換:21389754
4)將9754逆轉:21384579
因此21379854的下一個排列是21384579
#include <stdio.h> int a[10],N; int cmp(const void *a,const void *b) { return *(int*)a-*(int*)b; } int fac(); void Fun(); void Reverse(int m,int n); void Output(); int main() { int i; while (printf("\nPlease input N: "),scanf("%d",&N)!=EOF) { printf("Please input %d numbers:\n",N); for (i=0;i<N;i++) { scanf("%d",&a[i]); } qsort(a,N,sizeof(a[0]),cmp); //先將N個數排序 printf("These numbers are: \n"); for (i=0;i<N;i++) { printf("%3d",a[i]); } printf("\n"); Fun(); } return 0; } int fac() //求N的階乘,即全排列的個數 { int count=1,i=2; while (i<=N) { count*=i; i++; } return count; } void Fun() { int index1,index2,i,k,min,n,temp; //index1爲上述j下標,index2爲上述k下標 n=fac(); for (k=1;k<n;k++) //n次循環 { for (index1=N-2;index1>=0;index1--) //求index1下標 { if (a[index1]<a[index1+1]) { break; } } min=32767; for (i=index1+1;i<N;i++) //求index2 { if (a[i]>a[index1]) { if (a[i]<min) { min=a[i]; index2=i; } } } temp=a[index1]; //交換a[index1],a[index2] a[index1]=a[index2]; a[index2]=temp; Reverse(index1+1,N-1); //逆置a[index1]到a[N-1]的數 Output(); //輸出 } } void Reverse(int m,int n) { int temp; while (m<n) { temp=a[m]; a[m]=a[n]; a[n]=temp; m++; n--; } } void Output() { int i; for (i=0;i<N;i++) { printf("%3d",a[i]); } printf("\n"); }