There are several important principles for writing recursive Programs:
1. The problems to be solved can be divided into several problems and the original ones.
Similar).
2. Each subproblem must be larger than the original one.
Smaller(Even if the number one is smaller, it would be better if the scale can be quickly reduced ).
3. solve small enough subproblems directly to prevent them from being infinitely subdivided, that is, to prevent infinite recursion (recursive termination conditions are important ).
Let's first look at a simple recursive program. The following program calculates the factorial of integer N:
Int factorial (int n)
{
Return n <= 1? 1: N * factorial (n-1 );
}
The so-called recursive program means that the program calls itself during execution. For example, the above function factorial calls the function factorial in its function body. Each time a function is called, it generates a local variable
CopyThat is, the same is true for function calls. The main body of a recursive program consists of two parts: one is the Recursive Execution part, which contains the conditions required for Recursive Execution, and the other is the recursive termination part, which contains the recursive termination conditions. The above factorial program writes the two parts in a line of code and extracts them separately:
Int factorial (int n)
{
If (n <= 1) return 1; // recursive termination body
Return N * factorial (n-1); // Recursive Execution body
}
The following uses recursive program solutions for several typical algorithm problems as an example to analyze the simple rules that can be followed in recursive Programs.
1. All possible sum combinations of positive integer N. For example, given a positive integer 3, all and the sum equal to 3 are as follows:
3 = 3 + 0
3 = 2 + 1
3 = 1 + 1 + 1
The factor in one of the operators can only be a natural number, and the factor can be repeated.
This problem is the deformation of a combination problem. It is implemented using recursive Programs as follows (for analysis, see the Notes ):
# Define maxsize 50
Static int buff [maxsize]; // buffer for the combination of storage and formula Factors
/// Calculate the sum of the factors in the current and formula.
Int sum (INT buff [], int I)
{
Int sum = 0;
For (INT m = 0; m <= I; m ++)
Sum + = buff [m];
Return sum;
}
/// Print the sum that meets the conditions.
Void printfactor (INT buff [], int I, const int number)
{
Int COUNT = 0, M;
For (m = 0; m <= I; m ++)
Printf ("% 4D", buff [m]);
If (number = buff [0])
Printf ("% 4D", 0 );
Printf ("/N ");
}
/// Recursively solve all sum combinations.
/// I-the maximum value of the currently available natural number.
/// Top-number of factors in the current combination.
/// Number-the positive integer to be solved in the question and formula.
Void divide (int I, int top, int number)
{
For (Int J = I; j> 0; j --) // pay attention to the cyclic conditions here to effectively prevent repeated combinations.
{
Buff [Top] = J;
If (number = sum (buff, top) // first determine the recursive Stop Condition
Printfactor (buff, top, number );
Else if (number <sum (buff, top) // continue adding the factor in the Sum Formula
Continue;
If (top> = Number) // The factor in the sum cannot exceed the sum.
Continue;
Divide (J, top + 1, number); // reduce the problem scale and continue Recursion
}
Return;
}
Int main ()
{
Int I, Top = 0;
Int number = 8;
Printf ("input a Souce number :");
Scanf ("% d", & number );
I = number;
Divide (I, top, number );
Return 0;
}
2. Given a positive integer k and an arrangement of K positive integers in 1-K, for example, 1, 2, 3,..., K, we will find all the non-Intersecting arrangements with this arrangement.
The so-called non-intersection refers to the fact that the number of new and existing orders in the same position is different. For example, if k = 3, it is arranged as follows:
1 2 3 and 3 2 1 are intersection, because the second position is 2, and the Arrangement 1 2 3 and 3 1 2 are not intersection.
Problem Analysis: this problem is the deformation of the general arrangement problem. You only need to add the location restriction in the recursive program of the arrangement problem. The program is implemented as follows. For detailed analysis, see annotations.
Const int n = 5;
Int range [9] = {1, 2, 4, 5, 6, 7, 8, 9}; // arrange the predefined positions
/// Determine whether the selected number J has been used.
Bool selected (Int J, int * buffer)
{
For (INT I = 0; I <n; I ++)
If (buffer [I] = J)
Return true;
Return false;
}
/// Calculates the non-Intersecting arrangement.
/// I-the current position or number of elements in the current arrangement.
/// Buffer-stores the currently arranged arrays.
/// Count-stores the number of non-Intersecting arrays.
Void arrange (int I, int * buffer, Int & COUNT)
{
If (I = 0) // recursive termination condition
{
For (int K = 0; k <n; k ++)
Cout <buffer [k] <"";
Cout <Endl;
Count ++;
Return;
}
For (Int J = 1; j <= N; j ++) // select the number of places that can be placed at the current position in a loop.
{
If (selected (J, buffer) // determine whether the selected number is sufficient.
Continue;
Buffer [I-1] = J;
If (buffer [I-1] = range [I-1]) // The limit for backtracking, the number of the same location cannot be the same as the number of the corresponding location in the predefined Arrangement
Continue;
Arrange (I-1, buffer, count); // continue Recursion
}
Buffer [I-1] = 0; // backtracking, reinitializing the current location
}
Int main ()
{
Int buffer [N] = {0 };
Int COUNT = 0;
Arrange (n, buffer, count );
Cout <count <Endl;
Return 0;
}
Although the recursive program solution is elegant and concise, the program efficiency will gradually decrease as the number of non-recursive Programs increases, which is also a major defect of recursive Programs.
Copyright @ David 2006.11 in Beijing