Previous articles
1 Introduction-Basic Concepts of Data Structure
2 Introduction-Algorithm
3 Linear List-Sequence List and Linked List Concepts and Their Code Implementation
4 Search-Order + Half + Index + Hash
5 Insertion Sort-Hill Sort-Selection Sort-Bubble Sort-Quick Sort-Cardinal Sort-External Sort-Merge Sort
Article Directory
1 Definition of recursion
- A subroutine (or function) calls itself directly or indirectly through a series of call statements, which is called recursion.
- Recursion is a basic method of describing and solving problems.
Direct recursive call
void A()
{
...
A();
...
}
Indirect call recursion
void B()
{
...
C();
...
}
void C()
{
...
B();
...
}
2 Recursive and non-recursive solution of Fibonacci sequence
Tail recursion can be converted to non-recursive writing
Tail recursion means that recursion only occurs when return
Recursive solution
int f(int n)
{
if(n<=1)
return n;//结束条件
else
return(f(n-1)+f(n-2));//递归方程
}
Non-recursive solution
int f(int n)
{
int pre,now,next,j;
if(n<=1)return(n);
else
{
pre=0;now=1;
for(j=2;j<=n;j++)
{
next=pre+now;
pre=now;
now=next
}
return(next);
}
}
3 Recursive and non-recursive solutions for palindrome string detection
If a string is read from left to right and read from right to left is exactly the same (not case sensitive), then this string is called a palindrome. For example, "noon", "madam", etc. are all palindrome string.
Recursive solution
bool palindrome(string &s,unsigned h,unsigned t)
{
if (h>=t) return 1;
if(tolower(s[h])==tolower(s[t]))
return palindrome(s,h+1,t-1);
else
return 0;
}
Non-recursive solution
bool palindrome(string &s)
{
int h=0,t=strlen(s)-1;
while(h<=t)
{
if(s[h]!=s[t])return 0;
h++;t--;
}
return 1;
}
4 Divide and conquer recursion
4.1 Divide and conquer recursive thought
- Solve these k sub-problems separately. If the scale of the sub-problem is still not small enough, then divide it into k sub-problems, and proceed recursively until the problem is small enough to find its solution easily.
- Combine the solution of the small-scale problem that is found into the solution of a larger-scale problem, and gradually find the solution of the original problem from the bottom up.
4.2 Applicable conditions of the divide and conquer law
- The scale of the problem can be easily solved by reducing it to a certain extent;
- The problem can be decomposed into several smaller-scale identical problems, that is, the problem has the property of optimal substructure ( premise )
- The solutions of the sub-problems decomposed by the problem can be combined into the solution of the problem; ( if you have the first two but not the third, you can consider using greedy algorithm and dynamic programming )
- The sub-problems decomposed by the problem are independent of each other, that is, the sub-problems do not contain common sub-problems. ( This feature designs the efficiency of the divide-and-conquer method )
4.3 The basic steps of divide and conquer
Pay attention to the notes
{
if ( | P | <= n0) adhoc(P); //解决小规模的问题
divide P into smaller subinstances P1,P2,...,Pk;//分解问题
for (i=1,i<=k,i++)
yi=divide-and-conquer(Pi); //递归的解各子问题
return merge(y1,...,yk); //将各子问题的解合并为原问题的解
}
4.4 Three ways to solve the recursive complexity calculation
4.4.1 Substitution method
Prerequisite (ignore the details and add them if they are found to be important later)
T(n) consists of two parts, one isSum of calculation time for each small part + Decomposition time and reconciliation time f(n)
The main idea
- Guess the form of the solution.
- Use mathematical induction to find the constant that makes the solution really effective
4.4.2 Iterative method-direct expansion
4.4.3 Main method
5 Example application
Assuming that there are n data a[n], to print all the permutations of these n data, consider the recursive method PrintPermutation.
-
The element at the first position may be any of these n elements. You can use swap to exchange the first position with other positions to get the difference in the first position element, and the rest of the recursive call prints all The arrangement function PrintPermutation is completed. However, it should be noted that they should be exchanged back to facilitate correct handling later.
-
Inside the recursive function, the element at the current first position (the second position) will be exchanged with the remaining n-2 position elements; the element at the current first position (the third position) will be exchanged with the remaining n -3 position element exchange; ...; The element at the last nth position means that the previous n-1 positions have been processed and can be printed. So the recursive printing condition is position k=n, this is also a recursive exit
a[] stores the data k represents the first exchange position, generally 1, n is the number of data.
void PrintPermutation(int a[], int k, int n){
if (k == n){
for (int i = 1; i < n + 1; ++i){
cout << a[i] << " ";
}
cout << endl;
return;
}
else{
for (int i = k; i < n+1; ++i){
Swap(a[k], a[i]);
PrintPermutation(a, k + 1, n);
Swap(a[k], a[i]);
}
}
}
int main()
{
int *a, len;
cout << "len:" << endl;
cin >> len;
a = new int[len+1];
if (!a)return -1;
for (int i = 1; i < len + 1; ++i)
a[i] = i;
PrintPermutation(a, 1, len);
}
If there are omissions and errors, please point them out.