1
#include
<
stdio.h
>
2
3 #define LEFT -1
4 #define RIGHT 1
5
6 int get_max_moveable_index( int array_direction[], int array_permutation[], int num_of_ints);
7 void johnson_trotter( int n);
8 void swap_array( int array[], int i, int j);
9 void print_permutation( int value_table[], int direction_table[], int number_of_ints);
10 int main(){
11 int n;
12 printf( " Enter an integer n: " );
13 scanf( " %d " , & n);
14 johnson_trotter(n);
15 printf( " All permutations are generated!\r\n " );
16 return 0 ;
17 }
18
19
20
21 void johnson_trotter( int n){
22 // The johnson_trotter algorithm to generate all permutations of an integer set {1,2,...,n}
23 // Input: A positive integer n
24 // Output: a list of all permutations of {1,2,...,n}
25 int direction_array[n + 1 ];
26 int permutation_array[n + 1 ];
27 for ( int k = 1 ;k <= n;k ++ ){
28 direction_array[k] = LEFT;
29 permutation_array[k] = k;
30 }
31
32 // Initial
33 printf( " Initial:\r\n " );
34 print_permutation(permutation_array,direction_array,n);
35 int max_moveable_index;
36 int num_counter = 1 ;
37 while ((max_moveable_index = get_max_moveable_index(direction_array,permutation_array,n)) > 0 ){
38 int num_max_moveable = permutation_array[max_moveable_index];
39 // Print
40 printf( " Max Moveable:%d(%s)\r\n " ,num_max_moveable,direction_array[max_moveable_index] == 1 ? " --> " : " <-- " );
41 int pointed_index = max_moveable_index + direction_array[max_moveable_index];
42 swap_array(permutation_array,max_moveable_index,pointed_index);
43 swap_array(direction_array,max_moveable_index,pointed_index);
44 for ( int k = 1 ; k <= n; k ++ ){
45 if (permutation_array[k] > num_max_moveable)
46 direction_array[k] *= - 1 ;
47 }
48 print_permutation(permutation_array,direction_array,n);
49 num_counter ++ ;
50 }
51 printf( " Total permutations:%d\r\n " ,num_counter);
52 }
53 /* *
54 * @param array_direction: the direction array thats saves the directions of the numbers in permutation array_permutation
55 * @param array_permutation: the observed permutation
56 * @param num_of_ints: number of observed numbers
57 * @return the index of the largest moveable number in permutation array array_permutation
58 * */
59 int get_max_moveable_index( int array_direction[], int array_permutation[], int num_of_ints){
60 int num_of_max_moveable = 0 ; // the largest moveable number
61 int max_moveable_index = 0 ; // the index of the largest moveable number
62 // scan for all the moveable numbers and get the largest one of them
63 for ( int k = num_of_ints; k > 0 ; k -- ){
64 int index_pointed = k + array_direction[k]; // the index of the number that the observed number points to
65 int current_num = array_permutation[k];
66 // make sure that the current number is pointed to a valid position
67 if (index_pointed > 0 && index_pointed <= num_of_ints && array_permutation[index_pointed] < current_num){
68 // the current number is moveable
69 if (current_num > num_of_max_moveable){
70 // the current number is the largest moveable number
71 num_of_max_moveable = current_num;
72 max_moveable_index = k;
73 }
74 }
75 }
76 return max_moveable_index;
77 }
78 /* *
79 * @param array: the array in which two elements are swapped.
80 * @param i: the index of the first to-be-swapped element
81 * @param j: the index of the second to-be-swapped element
82 * */
83 void swap_array( int array[], int i, int j){
84 int tmp = array[i];
85 array[i] = array[j];
86 array[j] = tmp;
87 }
88
89 /* *
90 * prints a permutation and its relevant directions
91 * @param permutation_array:
92 * @param direction_array:
93 * @param number_of_ints: length of array. position zero is not used.
94 * */
95 void print_permutation( int permutation_array[], int direction_array[], int number_of_ints){
96 for ( int k = 1 ; k <= number_of_ints; k ++ ){
97 printf( " %4d(%s)\t " ,permutation_array[k],direction_array[k] == 1 ? " --> " : " <-- " );
98 }
99 printf( " \r\n " );
100 }
2
3 #define LEFT -1
4 #define RIGHT 1
5
6 int get_max_moveable_index( int array_direction[], int array_permutation[], int num_of_ints);
7 void johnson_trotter( int n);
8 void swap_array( int array[], int i, int j);
9 void print_permutation( int value_table[], int direction_table[], int number_of_ints);
10 int main(){
11 int n;
12 printf( " Enter an integer n: " );
13 scanf( " %d " , & n);
14 johnson_trotter(n);
15 printf( " All permutations are generated!\r\n " );
16 return 0 ;
17 }
18
19
20
21 void johnson_trotter( int n){
22 // The johnson_trotter algorithm to generate all permutations of an integer set {1,2,...,n}
23 // Input: A positive integer n
24 // Output: a list of all permutations of {1,2,...,n}
25 int direction_array[n + 1 ];
26 int permutation_array[n + 1 ];
27 for ( int k = 1 ;k <= n;k ++ ){
28 direction_array[k] = LEFT;
29 permutation_array[k] = k;
30 }
31
32 // Initial
33 printf( " Initial:\r\n " );
34 print_permutation(permutation_array,direction_array,n);
35 int max_moveable_index;
36 int num_counter = 1 ;
37 while ((max_moveable_index = get_max_moveable_index(direction_array,permutation_array,n)) > 0 ){
38 int num_max_moveable = permutation_array[max_moveable_index];
39 // Print
40 printf( " Max Moveable:%d(%s)\r\n " ,num_max_moveable,direction_array[max_moveable_index] == 1 ? " --> " : " <-- " );
41 int pointed_index = max_moveable_index + direction_array[max_moveable_index];
42 swap_array(permutation_array,max_moveable_index,pointed_index);
43 swap_array(direction_array,max_moveable_index,pointed_index);
44 for ( int k = 1 ; k <= n; k ++ ){
45 if (permutation_array[k] > num_max_moveable)
46 direction_array[k] *= - 1 ;
47 }
48 print_permutation(permutation_array,direction_array,n);
49 num_counter ++ ;
50 }
51 printf( " Total permutations:%d\r\n " ,num_counter);
52 }
53 /* *
54 * @param array_direction: the direction array thats saves the directions of the numbers in permutation array_permutation
55 * @param array_permutation: the observed permutation
56 * @param num_of_ints: number of observed numbers
57 * @return the index of the largest moveable number in permutation array array_permutation
58 * */
59 int get_max_moveable_index( int array_direction[], int array_permutation[], int num_of_ints){
60 int num_of_max_moveable = 0 ; // the largest moveable number
61 int max_moveable_index = 0 ; // the index of the largest moveable number
62 // scan for all the moveable numbers and get the largest one of them
63 for ( int k = num_of_ints; k > 0 ; k -- ){
64 int index_pointed = k + array_direction[k]; // the index of the number that the observed number points to
65 int current_num = array_permutation[k];
66 // make sure that the current number is pointed to a valid position
67 if (index_pointed > 0 && index_pointed <= num_of_ints && array_permutation[index_pointed] < current_num){
68 // the current number is moveable
69 if (current_num > num_of_max_moveable){
70 // the current number is the largest moveable number
71 num_of_max_moveable = current_num;
72 max_moveable_index = k;
73 }
74 }
75 }
76 return max_moveable_index;
77 }
78 /* *
79 * @param array: the array in which two elements are swapped.
80 * @param i: the index of the first to-be-swapped element
81 * @param j: the index of the second to-be-swapped element
82 * */
83 void swap_array( int array[], int i, int j){
84 int tmp = array[i];
85 array[i] = array[j];
86 array[j] = tmp;
87 }
88
89 /* *
90 * prints a permutation and its relevant directions
91 * @param permutation_array:
92 * @param direction_array:
93 * @param number_of_ints: length of array. position zero is not used.
94 * */
95 void print_permutation( int permutation_array[], int direction_array[], int number_of_ints){
96 for ( int k = 1 ; k <= number_of_ints; k ++ ){
97 printf( " %4d(%s)\t " ,permutation_array[k],direction_array[k] == 1 ? " --> " : " <-- " );
98 }
99 printf( " \r\n " );
100 }
采用的是Johnson_Trotter算法。很少在Linux下编程,编码有点乱。
源码下载:Johnson_trotter.cpp