今天在网上看到一个递归的总结,感觉不错,拿下来与大家分享!
//递归例子
//1。求1+2+。。+100的和
int sum(int n){
if(n==1)
return 1;
else return
n+sum(n-1);
}
#include <stdio.h>
// 2.求m*n的乘积
int multiply(int m,int n){
if(n==1)return m;
else return
m+multiply(m,n-1);
}
//3.求阶乘
long fac(int n){
if(n==1)return 1;
else return n*fac(n-1);
}
//4.求字符数组的转置
void reverse(char *p,int length,int n){
if(n<length){
reverse(p,length,n+1);
printf("%c",p[n]);
}
}
//5.求数组中的最大值
int max(int *a,int n){
if(n==1)
return a[0];
else {
if(a[n-1]>max(a,n-1)) return a[n-1];
else return max(a,n-1);
}
}
//6.打印$
//4444
//333
//22
//1
void printNumber(int n){
if(n>=1){
for(int i=1;i<=n;i++)
printf("%d",n);
printf("\n");
printNumber(n-1);
}
}
//6.打印$
//1
//22
//333
//4444
void printNumber2(int n){
if(n>0)
printNumber(n-1);
for(int i=1;i<=n;i++)
printf("%d",n);
printf("\n");
}
//7.计算费氏数列的变种
long clib(int n){
if(n==0||n==1) return n;
else return 4*clib(n-2)+5*clib(n-1);
}
//8.计算递推公式
long F(int a,int n){
if(n==0) return 1;
else return a*F(a,n/2);
}
//9最大公约数公式
int gcd(int n,int m){
if(n<m) return gcd(m,n);
if(m==0)
return n;
else return
gcd(m,n%m);
}
//10.折半查找的递退公式
int bsearch(int i[],int x,int n){
int
low=0,high=n-1;
while(low<=high){
int mid=low+high/1;
if(x==i[mid]) return mid;
else if(x<i[mid]) high=mid-1;
else
low=mid+1;
}
return
-1;
}
//11.求组合个数
//组合递推公式为comn(m,n)=comn(m-1,n-1)+comn(m-1,n);
long comn(int m,int n){
if(n==0||m==n)return 1;
else return comn(m-1,n-1)+comn(m-1,n);
}
//12。背包问题
int Knap(int s,int w[],int n){
if(s==0)
return 1;
if(s<0)
return 0;
if(s>0&&n<1)
return 0;
if(s>0&&n>=1){
if(Knap(s,w,n-1)==1) return 1;
else
if (Knap(s-w[n-1],w,n-1)==1) return
1;
}else return
0;
}
13.组合问题
#include <stdio.h>
#define maxN 100
int a[maxN];
int size;
long sum=0;
void comn(int m,int k){
for(int i=m;i>=k;i--){ //第一个数从n,n-1到k
a[k]=i;
if(k>1)comn(i-1,k-1);//下一层递归比上层递归m小1;
else {
//找到一组解,打印
++sum;
for(int j=size;j>0;j--)
printf("%d",a[j]);
printf("\n");
}
}
}
main(){
size=3;
comn(8,5);
printf("共有%d组解",sum);
while(1){}
}
14。排列问题,求n!的所有排列问题
#include <stdio.h>
int n = 0;
void swap(int *a, int *b)
{
int
m;
m =
*a;
*a =
*b;
*b =
m;
}
void perm(int list[], int k,
int m)
{
int
i;
if(k >
m){
for(i = 0; i <= m;
i++)
printf("%d ", list[i]);
printf("\n");
++n;
} else
{
for(i=k; i <= m; i++) {
swap(&list[k],
&list[i]);
perm(list, k + 1, m);
swap(&list[k], &list[i]);
}
}
}
int main()
{
int list[] = {1, 2,
3};
perm(list, 0,
2);
printf("total:%d\n", n);
for(int i = 0; i <= 2;
i++)
printf("%d ", list[i]);
while(1){}
return 0;
}
15.整数划分问题
整数划分问题是将一个正整数n拆成一组数连加并等于n的形式,且这组数中的最大加数不大于n。
如6的整数划分为
6
5 + 1
4 + 2, 4 + 1
+ 1
3 + 3, 3 + 2
+ 1, 3 + 1 + 1 + 1
2 + 2 + 2, 2
+ 2 + 1 + 1, 2 + 1 + 1 + 1 + 1
1 + 1 + 1 +
1 + 1 + 1
共11种。下面介绍一种通过递归方法得到一个正整数的划分数。
递归函数的声明为 int
split(int n, int m);其中n为要划分的正整数,m是划分中的最大加数(当m >
n时,最大加数为n),
1 当n = 1或m =
1时,split的值为1,可根据上例看出,只有一个划分1 或 1 + 1 + 1 + 1 + 1 + 1
可用程序表示为if(n
== 1 || m == 1) return 1;
2 下面看一看m 和
n的关系。它们有三种关系
(1) m
> n
在整数划分中实际上最大加数不能大于n,因此在这种情况可以等价为split(n, n);
可用程序表示为if(m
> n) return split(n,
n);
(2) m =
n
这种情况可用递归表示为split(n, m - 1) + 1,从以上例子中可以看出,就是最大加
数为6和小于6的划分之和
用程序表示为if(m
== n) return (split(n, m - 1) + 1);
(3) m
< n
这是最一般的情况,在划分的大多数时都是这种情况。
从上例可以看出,设m =
4,那split(6, 4)的值是最大加数小于4划分数和整数2的划分数的和。
因此,split(n,
m)可表示为split(n, m - 1) + split(n - m, m)
根据以上描述,可得源程序如下:
#include
<stdio.h>
int split(int n, int m)
{
if(n < 1 || m
< 1) return 0;
if(n == 1
|| m == 1) return 1;
if(n
< m) return split(n, n);
if(n == m) return (split(n, m
- 1) + 1);
if(n > m)
return (split(n, m - 1) + split((n - m), m));
}
int main()
{
printf("12的划分数: %d", split(12, 12));
return
0;
}
main(){
char a[]={'a','b','c','d'};
int b[]={1,20,100,-5,7};
int i[]={1,2,3,4,5,6,7,8};
//reverse(a,4,0);
//printNumber2(4);
printf("%d\n",bsearch(i,4,8));
while(1){};
}
分享到:
相关推荐
这是一种将大问题分解为若干个规模较小、相互独立且与原问题形式相同的子问题,然后递归地解决这些子问题,最后将子问题的解合并得到原问题的解的策略。分治法的核心思想是将问题的规模减小,直到问题变得足够简单,...
在《算法分析与设计教程...以上内容涵盖了算法设计与分析的基本要素,包括算法定义、分析方法、递归和分治策略的实际应用,以及排序、查找等相关算法的细节。理解这些知识点对于深入学习算法和提升编程能力至关重要。
整数划分方法1是一种在计算机科学和算法设计中常见的问题,它涉及到将一个给定的非负整数拆分为若干个正整数之和,这些正整数的和必须等于原始整数。这个问题通常用于解决各种数学问题,例如在游戏理论中的循环游戏...
根据提供的信息,我们可以总结出以下相关的IT知识点,主要聚焦于算法设计与分析方面: ### 一、算法导论概述 《算法导论》是一本经典的计算机科学教材,它由Thomas H. Cormen、Charles E. Leiserson、Ronald L. ...
- 免费馅饼问题关注的是如何在有限的时间内收集尽可能多的馅饼。通过动态规划可以找到最优解。 11. **棋盘分割(NOI’99)** - 棋盘分割问题要求将一个棋盘分割成若干部分,使得每部分的得分尽可能高。通过定义...
·有关递归求解的那一章中,不再包含迭代方法了。在第4.2节中,我们将递归树“提升”为一种方法。我们发现,与对递归式进行迭代相比,画出递归树后出错的可能性小了。但是,我们也指出了递归树的最佳用途,即利用它...
·有关递归求解的那一章中,不再包含迭代方法了。在第4.2节中,我们将递归树“提升”为一种方法。我们发现,与对递归式进行迭代相比,画出递归树后出错的可能性小了。但是,我们也指出了递归树的最佳用途,即利用它...
若干简单的例子... 186 匹配连续行(续前)... 186 匹配IP地址... 187 处理文件名... 190 匹配对称的括号... 193 防备不期望的匹配... 194 匹配分隔符之内的文本... 196 了解数据,做出假设... 198 去除...
这通常涉及收集表和索引的相关统计信息。 12. Oracle如何统计操作系统数据 Oracle可以监控和统计操作系统的相关性能指标,这对于诊断系统性能问题很有帮助。这涉及使用Oracle提供的数据字典视图和动态性能视图。 ...
由于篇幅关系,本书只介绍了很少一部分库函数, 其余部分读者可根据需要查阅有关手册。 还应该指出的是,在C语言中,所有的函数定义,包括主函数main在内,都是平行的。也就是说,在一个函数的函数体内, 不能再...
- **Stream流式计算**:Stream流式计算是一种新的数据处理模型,它可以将数据源转化为流,然后对流进行各种操作(如过滤、映射、排序等),最后收集结果。 #### 1.3 示例 在给定的部分内容中,通过一个具体的例子...
- 分治法的一种应用,将数组分成两半,递归地排序后再合并。 - 平均时间复杂度 O(nlogn)。 - **归并排序求逆序数**: - 在归并过程中统计逆序数的数量,可用于解决某些特殊问题。 #### 八、前缀和 - **前缀和...