(1) Non-recursive full permutation algorithm
The basic idea is:
1. Find the smallest of all the permutation P.
2. Find the Q,
3. Execute Step 2 in a loop until a maximum arrangement is found and the algorithm ends.
The following is a mathematical description:
Given the known sequence P = A1A2A3An (Ai! = Aj, (1 <= I <= n, 1 <= j <= n, I! = J ))
Find a minimum arrangement of P Pmin = P1P2P3Pn with Pi> P (I-1) (1 <I <= n)
Starting from Pmin, the current maximum sorting is always input and the next sorting is obtained.
Method:
1. From the low position to the high position (from the back to the front), find the "non-conforming trend" number. That is, find a Pi, so that Pi <P (I + 1 ).
If such pi is not found, we have found the last full arrangement and can return it.
2. In P (I + 1) P (I + 2) Pn, find a Pj and you will get Pj "just better than" Pi.
("Just greater than" means the smallest element in the set of all elements greater than Pi in P (I + 1) P (I + 2) Pn .)
3. Switch the position of Pi and Pj. Note: I and j values are not changed here, But Pi and Pj are changed.
4. After switching, P1P2P3Pn is not an accurate last arrangement. Based on the search in step 1, we have P (I + 1)> P (I + 2)>.> Pn
Even if Pi and Pj are exchanged, this is still the largest arrangement in this part. Inverted (to the smallest order) is the next order.
5. Repeat steps 1-4 until the "non-trend" number is not found in step 1.
Copy codeThe Code is as follows: // exchange the values of the two elements I and j in array.
Void swap (int * a, int I, int j)
{
A [I] ^ = a [j];
A [j] ^ = a [I];
A [I] ^ = a [j];
}
// Invert all the elements in array a between subscript I and subscript j.
Void reverse (int a [], int I, int j)
{
For (; I <j; ++ I, -- j)
{
Swap (a, I, j );
}
}
Void print (int a [], int length)
{
For (int I = 0; I <length; ++ I)
Cout <a [I] <"";
Cout <endl;
}
// Obtain the full order and print the result
Void combination (int a [], int length)
{
If (length <2) return;
Bool end = false;
While (true)
{
Print (a, length );
Int I, j;
// Find the subscript I of the element that does not conform to the trend
For (I = length-2; I> = 0; -- I)
{
If (a [I] <a [I + 1]) break;
Else if (I = 0) return;
}
For (j = length-1; j> I; -- j)
{
If (a [j]> a [I]) break;
}
Swap (a, I, j );
Reverse (a, I + 1, length-1 );
}
}
(2) Recursive Algorithms
So that E = {e1,..., en} indicates the set of n elements. Our goal is to generate all the arrangement modes of the set. Set Ei to E after removing element I. perm (X) indicates the arrangement of elements in set X. p e r m (X) indicates the arrangement obtained after ei is added before each arrangement in perm (X. For example, if E = {a, B, c}, E1 = {B, c}, perm (E1) = (B c, c B), e1. perm (E1) = (a B c, a c B ). For the basic part of recursion, n = 1 is used. When there is only one element, only one arrangement is possible, so perm (E) = (e), where e is the unique element in E. When n> 1, perm (E) = e1. perm (E1) + e2. p e r m (E2) + e3.perm (E3) + accept + en. perm (En ). This recursive definition uses n perm (X) to define perm (E), where each X contains n-1 elements. So far, the basic and recursive parts required for a complete recursive definition have been completed.
When n = 3 and E = (a, B, c), perm (E) =. perm ({B, c}) + B. perm ({a, c}) + c. perm ({a, B }). Similarly, according to recursive definitions, perm ({B, c}) = B. perm ({c}) + c. perm ({B}), so. perm ({B, c}) = AB. perm ({c}) + ac. perm ({B}) = a B. c + ac. B = (a B c, a c B ). B. perm ({a, c}) = ba. perm ({c}) + bc. perm ({a}) = B. c + B c. a = (B a c, B c a), c. perm ({a, B}) = ca. perm ({B}) + cb. perm ({a}) = c. B + c B. a = (c a B, c B ). So perm (E) = (a B c, a c B, B a c, B c a, c a B, c B ). Note. perm ({B, c}) actually contains two permutation Methods: abc and a c B, a is their prefix, and perm ({B, c}) is their suffix. Similarly, ac. perm ({B}) indicates the arrangement with a prefix of a c and a suffix of perm ({B. Program 1-1 0 converts the recursive definition of the above perm (E) into a C ++ function, this code outputs all the prefixes for l I s t [0: K-1], the way in which the suffix is l I s t [k: m. Call Perm (list, 0, n-1) to obtain all n of list [0: n-1! In this call, k = 0, m = n-1. Therefore, the prefix of the arrangement is empty and the suffix is list [0: n-1. When k is m, there is only one suffix l I s t [m], so list [0: m] is the output to be generated. When k <m, first use list [k] to exchange with each element in l I s t [k: m], and then generate list [k + 1: m], and use it as the suffix of list [0: k. S w a p is an inline function used to exchange values of two variables.Copy codeThe Code is as follows: template <class T>
Inline void Swap (T & a, T & B)
{
// Exchange a and B
T temp = a; a = B; B = temp;
}
Template <class T>
Void Perm (T list [], int k, int m)
{
// Generate all the sorting methods of list [k: m]
Int I;
If (k = m)
{
// Output an arrangement
For (I = 0; I <= m; I ++)
Cout <list [I];
Cout <endl;
}
Else // list [k: m] has multiple arrangement Modes
{
// Recursively generate these permutation Methods
For (I = k; I <= m; I ++)
{
Swap (list [k], list [I]);
Perm (list, k + 1, m );
Swap (list [k], list [I]);
}
}
}