C语言的六种常用算法

合集下载

C语言常用算法集合

C语言常用算法集合

1.定积分近似计算:/*梯形法*/double integral(double a,double b,long n) { long i;double s,h,x;h=(b-a)/n;s=h*(f(a)+f(b))/2;x=a;for(i=1;i<n;i++){x+=h;s+=h*f(x) ;}return(s);}/*矩形法*/double integral(double a,double b,long n) { long i;double t=0,h,x;h=(b-a)/n;x=a;for(i=0;i<n;i++){t+=h*f(x);x+=h;}return(t);}2. 生成斐波那契数列:/*直接计算*/int fib(int n){ int i,f1=1,f2=1,f;for(i=3;i<=n;i++){f=f1+f2;f1=f2;f2=f;}if(n==1||n==2) return 1;else return f;}/*递归调用*/void fib(int n,int*s){ int f1,f2;if(n==1||n==2) *s=1;else{ fib(n-1,&f1);fib(n-2,&f2);*s=f1+f2;}}3.素数的判断:/*方法一*/for (t=1,i=2;i<n; i++)if(n%i==0) t=0;if(t) printf("%d is prime",n);/*方法二*/for (t=1,i=2;i<n&&t; i++)if(n%i==0) t=0;if(t) printf("%d is prime",n);/*方法三*/for (i=2;i<n; i++)if(n%i==0) break;if(i==n) printf("%d is prime",n); /*方法四*/for(t=1,i=2; i<=(int)sqrt(n); i++)if(n%i==0){t=0;break;}if(t) printf("%d is prime",n);4.反序数:/*求反序数*/long fan(long n){ long k;for(k=0;n>0;n/=10)k=10*k+n%10;return k;}/*求回文数*/int f(long n){ long k,m=n;for(k=0;n>0;n/=10)k=10*k+n%10;if(m==k) return 1;return 0;}/*求整数位数*/int f(long n){ int count;for(count=0;n>0;n/=10)count++;return count;}5.求最大公约数:/*方法一*/int gcd(int x,int y){ int z;z=x<y?x:y;while(!(x%z==0&&y%z==0))/*x%z||y%z*/ z--;return z;}/*方法二*/int gcd(int x,int y){int r;while((r=x%y)!=0){x=y;y=r;}return y;}/*方法三*/int gcd(int a ,int b){ int r ;if((r=a%b)==0)return b;elsereturn gcd(b,r);}6.数组常用算法:查找:/*线性查找*/int find(int num,int x[],int key){ int i,m=-1;for(i=0;i<num;i++)if(x[i]==key){m=i;break;}return m;}/*折半查找*/int find(int x[],int num,int key){ int m=-1,low=0,high=num-1,mid;while(low<=high){mid=(low+high)/2;if(x[mid]==key){m=mid;break;}else if(x[mid]>key) high=mid-1;else low=mid+1;}return m;}/*折半查找(递归)*/int b_search(int x[ ],int low,int high,int key) {int mid;mid=(low+high)/2;if(x[mid]==key) return mid;if(low>=high) return -1;else if(key<x[mid])return b_search(x,low,mid-1,key);elsereturn b_search(x,mid+1,high,key); }/*寻找子串*/int find(char *s1,char *s2){ int i,k=0;while(s1[i]==s2[i]) i++;if(s2[i]==0) return k;s1++;k++;return -1;}分词:/*方法一*/void fen(char s[][10],char str){ int i,j,k;for(i=0,j=0,k=0;str[i]!=0;i++)if(isalpha(a[i]))s[j][k++]=str[i];else {s[j][k]=0;k=0;j++;}}}/*方法二*/#include<stdio.h>#include<string.h>void main(){ int i=0,n=0;char s[80],*p;strcpy(s,"It is a book.");for(p=s;p!='\0';p++)if(*p=='')i=0;elseif(i==0){n++;i=1;}printf("%d\n",n);getch();}排序:/*插入法排序*/void sort(int a[],int n){ int i,j,t;for(i=1;i<n;i++){t=a[i];for(j=i-1;j>=0&&t<a[j];j--)a[j+1]=a[j];a[j]=t;}}/*归并排序*/#define x 10#define y 10void com(int *a,int *b,int *c){ int i,j,k;for(i=0,j=0,k=0;i<=x&&j<=y;){if(a[i]<b[j]){c[k++]=a[i];i++;}else{c[k++]=b[j];j++;}}if(i<x) for(k=k-1;i<x;i++)c[k++]=a[i];if(j<x) for(k=k-1;j<y;j++)c[k++]=a[j]; }/*交换法排序1 冒泡排序*/void sort(int a[],int n){ int i,j,t,flag;for(i=0;i<n-1;i++){flag=1;for(j=0;j<n-1-i;j++)if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;flag=0;}if(flag) break;}}/*交换法排序2*/void sort(int a[],int n){ int i,j,t;for(i=0;i<n-1;i++)for(j=i+1;j<n;j++)if(a[i]>a[j]){t=a[i];a[i]=a[j];a[j]=t;}}/*选择法排序*/void sort(int a[],int n){ int i,j,point,t;for(i=0;i<n-1;i++){point=i;for(j=i+1;j<n;j++)if(a[point]<a[j]) point=j;if(point!=i){t=a[point];a[point]=a[i];a[i]=t;}}}7.一元非线性方程求根:/*牛顿迭代法求函数跟*/#include <stdio.h>#include <math.h>int main(void){ double x,x1,eps=1e-6,f,f1; /*误差为eps*/x=1.0; /*x=1.0是初值*/do{x1=x;f=6-x1*(5-x1*(4-3*x1)); /*f为f(x)函数*/f1=-5+x1*(8-9*x1); /*f1为f(x)的导函数*/x=x1-f/f1;f=6-x*(5-x*(4-3*x));}while(fabs(f)>=eps &&fabs(x-x1)>=eps);printf("x=%f",x);}/*二分法求函数跟*/#include <stdio.h>#include <math.h>double f(double x){ return 6-x*(5-x*(4-3*x)); /*f(x)函数*/}int main(void){ double a,b,c,x,eps=1e-6;do{scanf("%lf%lf",&a,&b);}while(f(a)*f(b)>0);if(fabs(f(a))<1e-6)x=a;else if (fabs(f(b))<1e-6)x=b;else {c=(b+a)/2;while(fabs(f(c))>eps&&fabs(b-a)>eps){if(f(a)*f(c)<0)b=c;elsea=c;c=(b+a)/2;}x=c;}printf("x=%f",x);}/*弦截法求函数跟*/c=(a*f(b)-b*f(a))/ (f(b)-f(a));while(fabs(f(c))>eps){if(f(a)*f(c)<0)b=c;elsea=c;c=(a*f(b)-b*f(a))/ (f(b)-f(a));}#include <stdio.h>void f();int main(void){ int x, loop=0;do{for(x=1;x<5;x++) {int x=2;printf("%d",x);}printf("%d ",x);f();loop++;}while(loop<1);getch();}void f(){ printf("%d",x++); }8.汉诺塔:#include<stdio.h>void Hanoi(int n, char A, char B, char C){if(n==1)printf("\n move %d from %c to %c",n,A,C);else{Hanoi(n-1,A,C,B);printf("\nmove %d from %c to %c",n,A,C);Hanoi(n-1,B, A, C);}}int main(void){ Hanoi(3,'A','B','C');getch();}9.建立链表:NODE *creat(void) /* void表示无参函数*/{NODE *head=NULL,*p1=NULL,*p2=NULL;long num;unsigned score;int n=0;do{scanf(“%ld%u”,&num,&score);if(num==0) break;n++;p1=(NODE *)malloc(sizeof(NODE));p1->data.num=num,p1->data.score=score;p1->next=NULL;if(n==1)head=p2=p1;else{p2->next=p1;p2=p1;}}while(1);return head;}10.级数的近似计算:#include <stdio.h>#include <math.h>int main(void){ double s=1,a=1,x,eps,f;int n,m;printf("input x and eps:");scanf ("%lf%lf",&x,&eps);for(n=1;fabs(a)>eps; n++){for(f=1,m=1;m<=n;m++)f*=m;a=pow(x,n)/f;s+=a;}printf("%f",s);}。

C语言常用算法

C语言常用算法

1.迭代法:
一般的一元五次方程或更高次的方程,以及几乎所有的微分方程、超越方程问题都无法用解析方法通过求根公式来求解,人们只能用数值方法求其近似值。

用事先估计的一个根的初始值X0,通过迭代算式X K+1=G(X K)求出一个近似的X1,再由求出X2,从而或得一个求解序列{ X0, X1, X2,…..X n,…}来逼近方程f(x)=0根。

这种求解过程成为迭代。

X1 x2=G(x1)
X3=G(x2)
X4=G(x3)
………
Xn=G(XN-1)
fabs(xn- xn-1)<1e-6
Xn+1=G(XN)
2.递归法:
递归是指一个过程直接或间接的调用它自身,递归过程必须有一个终止条件
3.递推法:
算法从递推的初始条件出发,应用递推公式对问题进行求解。

如Fibonacci 数列存在递推关系:
F(1)=1, F(2)=1, F(3)=2,
F(n)= F(n-1)+ F(n-2), (n>2)
若需求第30项的值,则依据公式,从初始条件F(1)=1,F(2)=1出发,逐步求出F(3),F(4),……,直到求出F(30)。

C语言用六种方法求定积分

C语言用六种方法求定积分

C语言用六种方法求定积分C语言中求定积分的方法主要有以下六种:基本公式法、数值积分法、Laplace变换法、微积分概念法、数值积分法和Monte Carlo方法。

下面将详细介绍每种方法的原理和实现。

1.基本公式法:基本公式法是求解定积分的最基本方法,根据不同函数的特点和性质,利用已知的积分公式进行求解。

例如,对于一次函数和常数函数,可以使用基本公式法求解。

2.数值积分法:数值积分法是通过将定积分转化为数值计算问题来求解。

常用的数值积分方法有矩形法、梯形法和辛普森法等。

这些方法基于将求积分区间分割成若干个小区间,然后在每个小区间上近似计算出函数的积分值,再将这些积分值加总得到最终结果。

3. Laplace变换法:Laplace变换法是一种利用Laplace变换求解微分方程的方法,也可以用来求解定积分。

通过将被积函数进行Laplace变换,然后利用Laplace变换公式求解积分,最后再求出反变换得到结果。

4.微积分概念法:微积分概念法是通过将定积分定义为函数曲线下的面积来求解。

具体做法是将被积函数图像与坐标轴围成的面积分为若干个小的矩形、梯形或曲线段以及一个小的区域。

然后根据图形的几何性质进行近似计算,将这些小面积相加得到最终结果。

5.数值积分法:数值积分法也是一种基于数值计算的方法,但与前面提到的数值积分法不同,它通过构造一系列特定形式的插值函数对被积函数进行逼近,然后计算插值函数的积分值来近似求解定积分。

常用的数值积分法有牛顿-科特斯公式和高斯-勒让德公式。

6. Monte Carlo方法:Monte Carlo方法是一种基于统计随机性的数值积分方法,它通过随机抽样来进行数值求解。

具体做法是在被积函数图像下随机抽取一系列点,根据这些随机点的坐标和函数值来估计函数的积分值。

通过对多次随机抽样的结果取平均可以得到定积分的近似值。

以上六种方法都可以用C语言来实现,具体的实现方法可以根据具体问题的特点和要求选择合适的算法和数据结构,然后编写相应的代码实现。

C语言常用算法总结

C语言常用算法总结

C语言常用算法总结1、冒泡排序算法:冒泡排序是一种简单的排序算法,它重复地遍历要排序的序列,一次比较两个相邻的元素如果他们的顺序错误就把他们交换过来。

时间复杂度为O(n^2)。

2、快速排序算法:快速排序是一种基于分治的排序算法,通过递归的方式将数组划分为两个子数组,然后对子数组进行排序最后将排好序的子数组合并起来。

时间复杂度为O(nlogn)。

3、插入排序算法:插入排序是一种简单直观的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描找到相应位置并插入。

时间复杂度为O(n^2)。

4、选择排序算法:选择排序是一种简单的排序算法,每次循环选择未排序部分的最小元素,并放置在已排序部分的末尾。

时间复杂度为O(n^2)。

5、归并排序算法:归并排序是一种稳定的排序算法,基于分治思想,将数组递归地分为两个子数组,将子数组排序后再进行合并最终得到有序的数组。

时间复杂度为O(nlogn)。

6、堆排序算法:堆排序是一种基于完全二叉堆的排序算法,通过构建最大堆或最小堆,然后依次将堆顶元素与末尾元素交换再调整堆,得到有序的数组。

时间复杂度为O(nlogn)。

7、二分查找算法:二分查找是一种在有序数组中查找目标元素的算法,每次将待查找范围缩小一半,直到找到目标元素或范围为空。

时间复杂度为O(logn)。

8、KMP算法:KMP算法是一种字符串匹配算法,通过利用模式字符串的自重复性,避免不必要的比较提高匹配效率。

时间复杂度为O(m+n),其中m为文本串长度,n为模式串长度。

9、动态规划算法:动态规划是一种通过将问题分解为子问题,并通过组合子问题的解来求解原问题的方法。

动态规划算法通常使用内存空间来存储中间结果,从而避免重复计算。

时间复杂度取决于问题规模。

10、贪心算法:贪心算法是一种通过选择局部最优解来构建全局最优解的算法并以此构建最终解。

时间复杂度取决于问题规模。

11、最短路径算法:最短路径算法用于求解图中两个节点之间的最短路径,常见的算法包括Dijkstra算法和Floyd-Warshall算法。

C语言算法全总结

C语言算法全总结

C语言算法全总结C语言是一种广泛应用于计算机科学领域的编程语言,具有高效、可移植和灵活的特点。

在程序设计中,算法是解决问题的一系列有序步骤,可以通过C语言来实现。

本文将为您总结C语言中常用的算法,包括排序算法、查找算法和图算法。

一、排序算法排序算法是将一组元素按照特定的顺序重新排列的算法。

常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序和归并排序。

这些算法的核心思想是通过比较和交换元素的位置来进行排序。

1.冒泡排序冒泡排序通过多次比较和交换相邻元素的位置来实现排序。

它的基本思想是将最大的元素不断地往后移动,直到整个序列有序。

2.选择排序选择排序通过每次选择最小的元素来实现排序。

它的基本思想是通过比较找到最小元素的位置,然后将其与第一个元素交换,接着在剩下的元素中继续找到最小元素并进行交换,如此重复直到整个序列有序。

3.插入排序插入排序通过构建有序序列,对未排序序列逐个元素进行插入,从而实现排序。

它的基本思想是将当前元素插入到前面已经排好序的序列中的适当位置。

4.快速排序快速排序是一种分治算法,通过选择一个基准元素,将其他元素划分为小于基准元素和大于基准元素的两部分,然后递归地对这两部分进行排序,最终实现整个序列有序。

5.归并排序归并排序也是一种分治算法,将序列分成两个子序列,分别对这两个子序列进行排序,然后将排序后的子序列合并成一个有序序列,从而达到整个序列有序的目的。

二、查找算法查找算法是在一个数据集合中寻找特定元素的算法。

常见的查找算法包括线性查找、二分查找和散列查找。

这些算法的核心思想是通过比较元素的值来确定待查找元素的位置。

1.线性查找线性查找是从数据集合的开头开始,依次比较每个元素的值,直到找到目标元素为止。

它的时间复杂度为O(n),其中n为数据集合的大小。

2.二分查找二分查找是针对有序序列进行查找的算法,它的基本思想是通过不断缩小查找范围,将目标元素与中间元素进行比较,从而确定待查找元素的位置。

C语言常用算法

C语言常用算法

} 插入法排序的要领就是每读入一个数立即插入到最终存放的数组中,每次插入都使得该数组有序。
例 2、任意读入 10 个整数,将其用插入法按降序排列后输出。
#define n 10
main()
{int a[n],i,j,k,x;
scanf("%d",&a[0]); /*读入第一个数,直接存到 a[0]中*/
if(b>c) { t=b; b=c; c=t; } printf("%d,%d,%d\n",a,b,c);}
2.累加
C 语言常用算法
累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而
实现累加功能。“A”通常是有规律变化的表达式,s 在进入循环前必须获得合适的初值,通常为 0。
C 语言常用算法
②除第 1 个数以外,再从其余 n-1 个数中找出最小数(即 n 个数中的次小数)的下标,将此数 与第 2 个数交换位置;
③重复步骤①n-1 趟,即可完成所求。
例 1、任意读入 10 个整数,将其用选择法按升序排列后输出。
#define n 10
main()
{int a[n],i,j,k,t;
3.查找
(1)顺序查找(即线性查找) 顺序查找 的思路是:将待 查找的量与数组中 的每一个元素进 行比较,若有一个 元素与之相等
则找到;若没有一个元素与之相等则找不到。 例 1、任意读入 10 个数存放到数组 a 中,然后读入待查找数值,存放到 x 中,判断 a 中有无与 x 等值的数。 #define N 10 main() {int a[N],i,x; for(i=0;i<N;i++) scanf("%d",&a[i]); /*以下读入待查找数值*/

常用算法设计方法C语言

常用算法设计方法C语言

常用算法设计方法C语言常用算法设计方法 (1)一、迭代法 (1)二、穷举搜索法 (2)三、递推法 (6)四、递归 (7)五、回溯法 (15)六、贪婪法 (28)七、分治法 (33)八、动态规划法 (39)常用算法设计方法要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。

计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。

算法数据结构是程序的两个重要方面。

算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。

指令正确地描述了要完成的任务和它们被执行的顺序。

计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。

通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。

其次是算法所需要的存储空间少和执行更快等。

算法设计是一件非常困难的工作,经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。

另外,为了更简洁的形式设计和藐视算法,在算法设计时又常常采用递归技术,用递归描述算法。

一、迭代法迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。

设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:选一个方程的近似根,赋给变量x0;将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。

若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。

上述算法用C程序的形式表示为:【算法】迭代法求方程的根{ x0=初始近似根;d o {x1=x0;x0=g(x1);/*按特定的方程计算新的近似根*/} while ( fabs(x0-x1)>Epsilon);p rintf(“方程的近似根是%f\n”,x0);}迭代算法也常用于求方程组的根,令X=(x0,x1,…,xn-1)设方程组为:xi=gi(X) (I=0,1,…,n-1)则求方程组根的迭代算法可描述如下:【算法】迭代法求方程组的根{ for (i=0;i<n;i++)x[i]=初始近似根;do {for (i=0;i<n;i++)y[i]=x[i];for (i=0;i<n;i++)x[i]=gi(X);for (delta=0.0,i=0;i<n;i++)if (fabs(y[i]-x[i])>delta)delta=fabs(y[i]-x[i]);} while (delta>Epsilon);for (i=0;i<n;i++)printf(“变量x[%d]的近似根是%f”,I,x[i]);printf(“\n”);}具体使用迭代法求根时应注意以下两种可能发生的情况:如果方程无解,算法求出的近似根序列就不会收敛,迭代过程会变成死循环,因此在使用迭代算法前应先考察方程是否有解,并在程序中对迭代的次数给予限制;方程虽然有解,但迭代公式选择不当,或迭代的初始近似根选择不合理,也会导致迭代失败。

C语言中的算法实现

C语言中的算法实现

C语言中的算法实现算法是计算机科学中非常重要的概念,它是解决问题的一系列步骤或指令集。

在C语言中,我们可以使用不同的方法来实现算法。

本文将介绍一些常见的C语言算法实现方式。

一、排序算法1. 冒泡排序冒泡排序是一种简单但效率较低的排序算法。

它通过不断比较相邻的元素,并按照规则交换它们的位置,直到整个序列排序完成。

2. 选择排序选择排序是一种简单而直观的排序算法。

它每次从未排序的序列中选择最小(或最大)的元素,并将其放置在已排序序列的末尾。

3. 插入排序插入排序是一种简单且高效的排序算法。

它通过构建有序序列,对未排序的元素逐个插入到已排序的序列中,直到所有元素都被插入完成。

二、查找算法1. 顺序查找顺序查找是一种简单的查找算法。

它从列表的开头开始逐个比较元素,直到找到目标元素或查找完整个列表。

2. 二分查找二分查找是一种高效的查找算法,但要求列表必须是有序的。

它通过将待查找区域分成两部分,判断目标元素落在哪一部分,从而缩小查找范围,直到找到目标元素或确定不存在。

三、递归算法递归是一种常用的算法设计技巧。

它通过在函数内调用自身来解决相同问题的不同实例。

在C语言中,递归函数需要定义出口条件,以避免无限递归。

四、动态规划算法动态规划是一种用于解决具有重叠子问题和最优子结构性质的问题的方法。

它将问题分解为一系列子问题,并以自底向上的方式求解子问题,最终得到整体问题的解。

在C语言中,可以使用循环、数组和指针等特性来实现动态规划算法,从而有效地解决问题。

五、图算法图是一种用于描述对象之间关系的数据结构,图算法是解决图相关问题的一类算法。

常见的图算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。

六、字符串算法字符串算法用于处理字符串相关的问题,如字符串匹配、编辑距离等。

C语言提供了一系列字符串处理函数,如strlen、strcpy等,可以方便地实现字符串算法。

七、数学算法C语言在数学算法方面提供了丰富的库函数支持,如求平方根、对数、指数等。

C语言常用简单算法

C语言常用简单算法

C语言常用简单算法C语言是一门功能强大的编程语言,其算法也是很多的。

下面是一些常用的简单算法:1.二分查找算法:二分查找是一种在有序数组中查找特定元素的算法。

它的基本思想是首先在数组的中间位置找到待查找的元素,如果该元素等于目标值,则查找成功;如果该元素大于目标值,说明目标值在数组的前半部分,则在前半部分继续进行查找;如果该元素小于目标值,则说明目标值在数组的后半部分,则在后半部分继续进行查找。

重复以上步骤,直到找到目标值或者确定目标值不存在。

2.冒泡排序算法:冒泡排序是一种简单直观的排序算法。

它的基本思想是通过反复交换相邻的两个元素,将较大的元素逐渐往后移动,从而实现排序的目的。

具体实现时,每一轮比较都会使最大的元素移动到最后。

3.插入排序算法:插入排序是一种简单直观的排序算法。

它的基本思想是将数组分成已排序部分和未排序部分,每次从未排序部分取出一个元素,然后将该元素插入到已排序部分的合适位置,从而实现排序的目的。

4.选择排序算法:选择排序是一种简单直观的排序算法。

它的基本思想是每次选择一个最小(或最大)的元素放到已排序部分的末尾,从而实现排序的目的。

具体实现时,每一轮选择都通过比较找出未排序部分的最小(或最大)元素。

5.快速排序算法:快速排序是一种高效的排序算法。

它的基本思想是通过选取一个基准元素,将数组分成两个子数组,一个子数组中的元素都小于基准元素,另一个子数组中的元素都大于基准元素,然后对这两个子数组分别进行快速排序,最终实现排序的目的。

6.斐波那契数列算法:斐波那契数列是一列数字,其中每个数字都是前两个数字之和。

常见的斐波那契数列算法有递归算法和迭代算法。

递归算法通过反复调用自身来计算斐波那契数列的值,而迭代算法则通过循环来计算。

7.求最大公约数算法:求两个数的最大公约数是一种常见的问题。

常见的求最大公约数的算法有欧几里得算法和辗转相除法。

欧几里得算法通过不断用较小数除以较大数的余数,直到余数为0,得到最大公约数。

C语言入门必学—10个经典C语言算法

C语言入门必学—10个经典C语言算法

C语言入门必学—10个经典C语言算法C语言是一种广泛使用的编程语言,具有高效、灵活和易学的特点。

它不仅在软件开发中被广泛应用,也是计算机科学专业的必修课。

在学习C语言的过程中,掌握一些经典的算法是非常重要的。

本文将介绍10个经典C语言算法,帮助读者更好地了解和掌握C语言。

一、冒泡排序算法(Bubble Sort)冒泡排序算法是最简单、也是最经典的排序算法之一。

它通过不断比较相邻的元素并交换位置,将最大(或最小)的元素逐渐“冒泡”到数组的最后(或最前)位置。

二、选择排序算法(Selection Sort)选择排序算法是一种简单但低效的排序算法。

它通过不断选择最小(或最大)的元素,并与未排序部分的第一个元素进行交换,将最小(或最大)的元素逐渐交换到数组的前面(或后面)。

三、插入排序算法(Insertion Sort)插入排序算法是一种简单且高效的排序算法。

它通过将数组分为已排序和未排序两个部分,依次将未排序部分的元素插入到已排序部分的合适位置。

四、快速排序算法(Quick Sort)快速排序算法是一种高效的排序算法。

它采用了分治的思想,通过将数组分为较小和较大两部分,并递归地对两部分进行排序,最终达到整个数组有序的目的。

五、归并排序算法(Merge Sort)归并排序算法是一种高效的排序算法。

它采用了分治的思想,将数组一分为二,递归地对两个子数组进行排序,并将结果合并,最终得到有序的数组。

六、二分查找算法(Binary Search)二分查找算法是一种高效的查找算法。

它通过不断将查找范围折半,根据中间元素与目标值的大小关系,缩小查找范围,最终找到目标值所在的位置。

七、递归算法(Recursive Algorithm)递归算法是一种通过自我调用的方式解决问题的算法。

在C语言中,递归算法常用于解决树的遍历、问题分解等情况。

八、斐波那契数列算法(Fibonacci Sequence)斐波那契数列是一列数字,其中每个数字都是前两个数字的和。

C语言程序设计的常用算法

C语言程序设计的常用算法

C语言程序设计的常用算法1.排序算法-冒泡排序:通过多次比较和交换来将最大(小)的数移到最后(前),时间复杂度为O(n^2)。

适用于数据较少、数据基本有序的情况。

- 快速排序:通过一趟排序将待排序序列分隔成独立的两部分,其中一部分的所有元素都比另一部分的所有元素小。

然后递归地对两部分进行排序,时间复杂度为O(nlogn)。

适用于大规模数据的排序。

-插入排序:将待排序序列分为已排序和未排序两部分,每次从未排序部分取一个元素插入到已排序部分的适当位置,时间复杂度为O(n^2)。

适用于数据量较小的排序场景。

- 归并排序:将待排序序列分为若干个子序列,分别进行排序,然后再将排好序的子序列合并成整体有序的序列,时间复杂度为O(nlogn)。

适用于需要稳定排序且对内存空间要求不高的情况。

2.查找算法-顺序查找:从头到尾依次对每个元素进行比较,直到找到目标元素或者遍历完整个序列。

时间复杂度为O(n)。

- 二分查找:对于有序序列,将序列的中间元素与目标元素进行比较,根据比较结果缩小查找范围,直到找到目标元素或者查找范围为空。

时间复杂度为O(logn)。

3.图算法-广度优先(BFS):从给定的起始顶点开始,按照“先访问当前顶点的所有邻接顶点,再依次访问这些邻接顶点的所有未访问过的邻接顶点”的顺序逐层访问图中的所有顶点。

适用于寻找最短路径、连通性等问题。

-深度优先(DFS):从给定的起始顶点开始,按照“先递归访问当前顶点的一个邻接顶点,再递归访问这个邻接顶点的一个邻接顶点,直到无法再继续递归”的方式遍历图中的所有顶点。

适用于寻找路径、判断连通性等问题。

4.动态规划算法-背包问题:给定一个背包容量和一组物品的重量和价值,选择一些物品装入背包,使得装入的物品总重量不超过背包容量,且总价值最大。

利用动态规划的思想可以通过构建二维数组来解决该问题。

-最长公共子序列(LCS):给定两个序列,找出一个最长的子序列,且该子序列在两个原序列中的顺序保持一致。

C语言常用算法大全

C语言常用算法大全

C语言常用算法大全1.排序算法-冒泡排序:依次比较相邻的两个元素,如果顺序不对则交换,每轮找出一个最大或最小的元素-选择排序:从未排序的元素中选择最小或最大的放到已排序的最后,以此类推-插入排序:将未排序的元素插入到已排序的合适位置,从后向前进行比较和交换-快速排序:选择一个基准元素,将小于基准元素的放在左边,大于基准元素的放在右边,然后对左右两边递归地进行快速排序-归并排序:将待排序的序列不断划分为左右两部分,分别排序后再将排序好的左右两部分按顺序合并-堆排序:构建大顶堆,将堆顶元素与末尾元素交换,然后重新调整堆,重复这个过程直到排序完成2.查找算法-顺序查找:从给定的元素序列中逐个比较,直到找到目标元素或遍历完整个序列-二分查找:对于有序序列,在序列的中间位置比较目标元素和中间元素的大小关系,通过每次缩小一半的范围来查找目标元素-插值查找:根据目标元素与有序序列的最小值和最大值的比例推测目标元素所在的位置,然后递归地进行查找-斐波那契查找:根据斐波那契数列的性质来确定目标元素所在的位置,然后递归地进行查找3.图算法-深度优先(DFS):从图的一些顶点出发,依次访问其未被访问过的邻接顶点,直到所有顶点都被访问过为止-广度优先(BFS):从图的一些顶点出发,逐层遍历图的顶点,直到所有顶点都被访问过为止- 最小生成树算法:Prim算法和Kruskal算法,用于找到连接图中所有顶点的最小权值边,构成一棵包含所有顶点的生成树- 最短路径算法:Dijkstra算法和Floyd-Warshall算法,用于找到图中两个顶点之间的最短路径-拓扑排序:用于有向无环图(DAG)中的顶点排序,确保排序后的顶点满足所有依赖关系-关键路径算法:找出网络中的关键路径,即使整个工程完成的最短时间4.字符串算法- KMP算法:通过预处理模式串构建next数组,利用next数组在匹配过程中跳过一部分不可能匹配的子串- Boyer-Moore算法:从模式串的末尾开始匹配,利用坏字符和好后缀规则进行跳跃匹配- Rabin-Karp算法:利用哈希函数对主串和匹配串的子串进行哈希计算,然后比较哈希值是否相等- 字符串匹配算法:BM算法、Shift-And算法、Sunday算法等,用于寻找模式串在主串中的出现位置5.动态规划算法-最长公共子序列(LCS):用于寻找两个序列中最长的公共子序列-最长递增子序列(LIS):用于寻找给定序列中最长的递增子序列-0-1背包问题:将有限的物品放入容量为C的背包中,使得物品的总价值最大-最大子数组和:用于求解给定数组中连续子数组的最大和-最大正方形:在给定的0-1矩阵中,找出只包含1的最大正方形的边长这些算法是在C语言中常用的算法,它们涵盖了排序、查找、图、字符串和动态规划等多个领域。

C语言的六种常用算法

C语言的六种常用算法

C语言的六种常用算法C语言是一种非常流行的编程语言,广泛应用于各种领域中。

在C语言中,有许多常用的算法,可以用来解决各种问题。

下面我们将详细介绍C语言中的六种常用算法。

1.排序算法:排序算法可以将一组数据按照一定的规则进行排序。

常见的排序算法有冒泡排序、选择排序、插入排序、快速排序等。

这些排序算法的原理各有不同,但都可以实现对数据的排序。

排序算法对于处理大量数据的应用非常重要,可以提高查找、统计等操作的效率。

2.查找算法:查找算法是指在一组数据中寻找特定元素的过程。

常见的查找算法有线性查找、二分查找、哈希查找等。

这些算法的实现方式不同,但都可以高效地找到目标元素。

查找算法广泛应用于数据库查询、引擎等需要快速查找数据的场景中。

3.图算法:图算法是针对图结构进行的一系列操作。

图是由顶点和边组成的数据结构,可以用来表示各种关系。

在图算法中,常见的操作包括遍历、连通性判断、最短路径查找等。

图算法在网络分析、社交网络分析、运输规划等领域中有着广泛的应用。

4.动态规划算法:动态规划算法是一种解决多阶段决策问题的方法。

它将问题划分为若干个阶段,每个阶段都有一系列可选的决策。

通过求解每个阶段的最优决策,最终得到整个问题的最优解。

动态规划算法在最短路径问题、背包问题、序列比对等领域中有着重要的地位。

5.深度优先算法:深度优先算法是一种遍历图或树的方法。

它从一个起始节点开始,沿着一条路径尽可能远地,直到遇到死路才返回并尝试其他路径。

深度优先算法常用于解决迷宫问题、图的连通性判断等。

6.广度优先算法:广度优先算法是一种遍历图或树的方法。

它从一个起始节点开始,首先访问所有相邻节点,然后再访问它们的相邻节点,以此类推,直到遍历完所有节点。

广度优先算法常用于寻找最短路径、社交网络分析等。

以上就是C语言中的六种常用算法。

这些算法在各自的领域中有着广泛的应用,对于解决各种问题起到了重要的作用。

对于想要学习C语言的人来说,掌握这些算法是非常重要的一步。

c语言常用算法

c语言常用算法
(2)任意位数的分离:
123456789 13579
使用循环
例如:把分离出来的奇数,组成新的数
s=0
i=1
while(n!=0)
{
a=n%10;
if(a%2==1)
{
s=s+a*i;
i=i*10;
}
n=n/10;
}
6.求最大值和最小值(使用数组+循环)
假设第一个数是最大的或最小值,然后与后面的每一个数进行比较,如果后面比它大或比它小,就把这个数作为目前的最大值或最小值,直到比较完最后一个元素
a[j+1]=t;
}
讲50、
break;
if(i>=n-1)
说明是素数
5.整数的分离 :
(1)四位数的分离
例如:1234
4=1234%10
3=1234/10%10
2=1234/100%10
1=1234/1000
例如:统计出1~100范围内偶数的个数
n=0;
for(i=1;i<=100;i++)
if(i%2==0)
n=n+1;
4.素数:只能被1和本身整除的数是素数
例如:判断n是否是素数
for(i=2;i<n;i++)
if(n%i==0)
常用算法:
1.两数交换
引入中间变量,通过三条语句=a
a=b
b=c
2.累加和累乘
累加的基本格式 :s=s+i
保存累加和的变量初值为0,通过循环实现
例如:求1+2+3...+100

C语言的六种常用算法

C语言的六种常用算法

C语言的六种常用算法C语言是一种广泛使用的编程语言,它不仅支持基本的算术运算,还提供了一些常用的高级算法来解决各种问题。

下面将介绍C语言中的六种常用算法。

1.排序算法:排序算法用于按特定的顺序重新排列一组数据。

常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序和归并排序。

这些算法的时间复杂度和空间复杂度各不相同,可以根据不同的需求选择合适的排序算法。

2.算法:算法用于在一组数据中查找特定的元素。

常见的算法包括线性、二分和哈希。

线性从列表的一端开始逐个比对,直到找到目标元素或完整个列表。

二分是一种高效的算法,它将目标元素与列表的中间元素进行比较,然后根据比较结果将范围缩小一半,重复此过程,直到找到目标元素。

3.图算法:图算法用于解决与图相关的问题,如最短路径问题、最小生成树问题和网络流问题。

常见的图算法包括广度优先(BFS)和深度优先(DFS),它们用于遍历图的节点。

Dijkstra算法用于求解最短路径问题,Prim算法用于求解最小生成树问题。

4.动态规划算法:动态规划算法用于解决最优化问题,将原始问题分解为子问题,并记录子问题的解,以避免重复计算。

常见的动态规划算法包括0/1背包问题、最长公共子序列问题和矩阵链乘法问题。

这些问题都可以通过建立递推关系和使用动态规划表格求解。

5.贪心算法:贪心算法每次取最优解,然后将剩余的子问题交给下一次迭代。

它通常适用于解决一些具有最优子结构的问题。

常见的贪心算法包括霍夫曼编码、最小生成树问题和拟阵问题。

6.分治算法:分治算法将问题分解为若干个规模较小且相互独立的子问题,然后分别解决子问题,最后合并子问题的结果得到原始问题的解。

常见的分治算法包括快速排序、归并排序和大整数乘法。

这些算法利用递归的思想,将问题逐层分解,直到问题规模足够小,可以直接解决。

以上是C语言中的六种常用算法。

每种算法都有其适用的场景和特点,根据实际需求选择合适的算法可以提高程序的效率和性能。

c语言常用算法

c语言常用算法

c语言常用算法一、前言C语言是一种高效、快速的编程语言,被广泛应用于各种领域。

在C 语言中,算法是非常重要的部分,因为它们能够帮助我们解决许多实际问题。

本文将介绍C语言中常用的算法。

二、排序算法1.冒泡排序冒泡排序是一种简单的排序算法,它通过不断交换相邻两个元素的位置来将最大的元素放到最后。

具体实现如下:```void bubble_sort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];}}}}```2.选择排序选择排序也是一种简单的排序算法,它通过不断选择最小元素并放到前面来完成排序。

具体实现如下:```void selection_sort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {int min_index = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[min_index]) {min_index = j;}}int temp = arr[i];arr[i] = arr[min_index];}}```3.插入排序插入排序是一种简单的排序算法,它通过将元素逐个插入到已排好序的序列中来完成排序。

具体实现如下:```void insertion_sort(int arr[], int n) {for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}}```4.快速排序快速排序是一种高效的排序算法,它通过选取一个基准元素并将数组分为两部分来完成排序。

c语言常见算法

c语言常见算法

c语言常见算法C语言是一种非常流行的编程语言,广泛应用于软件开发和计算机科学领域。

在C语言中,算法是解决问题的关键步骤。

本文将介绍一些常见的C语言算法,包括排序算法、搜索算法和递归算法。

一、排序算法1. 冒泡排序算法冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的两个元素,并交换它们的位置,直到整个列表排序完成。

2. 插入排序算法插入排序算法通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

3. 快速排序算法快速排序是一种高效的排序算法,它通过选择一个元素作为基准,将列表分为两部分,一部分小于基准,一部分大于基准,然后递归地对两部分进行排序。

二、搜索算法1. 线性搜索算法线性搜索算法逐个地检查列表中的元素,直到找到目标元素或者遍历完整个列表。

2. 二分搜索算法二分搜索算法适用于已排序的列表。

它通过比较目标元素和列表的中间元素,将列表分为两部分,然后在适当的部分继续搜索,直到找到目标元素或者确定目标元素不存在。

三、递归算法递归算法是一种自我调用的算法,它将问题分解成更小的子问题,然后在子问题上递归地调用自身,直到达到基本情况。

对于C语言中的算法来说,递归函数的编写非常重要。

需要确保递归的终止条件,并正确处理递归调用中传递的参数。

四、其他常见算法1. 图算法图算法是解决与图相关的问题的算法。

它可以解决最短路径问题、最小生成树问题等。

2. 动态规划算法动态规划算法是一种通过将问题分解成更小的子问题来解决复杂问题的算法。

它通常用于解决最优化问题。

3. 贪心算法贪心算法通过每一步选择当前最优解来构建问题的解决方案。

它通常不能保证找到全局最优解,但在某些情况下可以得到较好的近似解。

总结C语言常见算法涵盖了排序算法、搜索算法、递归算法以及其他常用的算法。

对于每个算法,我们都介绍了其基本原理和应用场景。

在实际编程中,根据具体的问题,选择合适的算法是非常重要的。

熟悉C语言中的常见算法,可以帮助程序员更好地解决问题,提高代码的效率与质量。

C语言最常用的六种排序方法详解

C语言最常用的六种排序方法详解

1.冒泡排序:
2.简单选择排序:
3.快速排序:
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

4.直接插入排序:
5.折半插入排序:
折半插入排序(binary insertion sort)是对插入排序算法的一种改进,在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为
a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素小,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。

代码:
6.希尔排序:。

C语言常用算法归纳

C语言常用算法归纳

C语言常用算法归纳C语言是一种常用的编程语言,广泛应用于各种计算机领域。

在C语言中,算法是一种解决问题的方法论,是实现程序的关键所在。

本文将介绍C语言常用的算法,并对其进行归纳总结。

1.排序算法排序算法是将一组数据按照一定的顺序重新排列的过程。

常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。

-冒泡排序:该算法比较相邻的两个元素,并将较大的元素向后移动,重复此过程直到序列有序。

-选择排序:该算法通过不断选择最小的元素,并放到已排序部分的末尾,重复此过程直到整个序列有序。

-插入排序:该算法将元素逐个插入到已排好序的序列中,重复此过程直到整个序列有序。

-快速排序:该算法通过选择一个基准元素,将元素分为两个分区,并对每个分区递归地快速排序,最终将整个序列有序。

-归并排序:该算法将序列分为两个部分,并对每个部分递归地归并排序,最后将两个有序的部分归并。

上述排序算法中,冒泡排序和选择排序的时间复杂度为O(n^2),插入排序的时间复杂度为O(n^2)或O(n),快速排序和归并排序的平均时间复杂度为O(nlogn)。

2.查找算法查找算法是在一组数据中找到指定的元素的过程。

常见的查找算法包括线性查找、二分查找、哈希查找等。

-线性查找:该算法从序列的首个元素开始,逐个比较元素,直到找到指定元素或遍历完整个序列。

-二分查找:该算法通过比较中间元素和目标元素的大小关系,逐渐缩小查找范围,最终找到目标元素。

-哈希查找:该算法通过将元素与哈希函数的运算结果关联,将元素存储在哈希表中;查询时,通过哈希函数确定元素的位置,从而快速查找。

二分查找的时间复杂度为O(logn),哈希查找的平均时间复杂度为O(1)。

3.字符串算法字符串算法是对字符串进行处理和操作的一系列算法。

常见的字符串算法包括字符串复制、字符串连接、字符串比较、字符串截取等。

- 字符串复制:可以使用strcpy函数实现字符串复制。

例如,strcpy(dest, src)将将src字符串复制到dest字符串中。

c分类算法

c分类算法

在C语言中,有许多种常用的分类算法可以用于数据挖掘和机器学习任务。

以下是一些常见的C语言实现的分类算法:1. 决策树(Decision Tree):ID3算法:一种基于信息熵的决策树构建算法。

C4.5算法:ID3算法的改进版本,使用信息增益率代替信息熵,并支持处理连续属性。

2. 朴素贝叶斯(Naive Bayes):朴素贝叶斯分类器是一种基于贝叶斯定理的概率分类模型,尤其适用于文本分类问题。

在C语言中,可以通过计算每个特征的条件概率和先验概率来实现。

3. K-最近邻(K-Nearest Neighbors, KNN):KNN是一种基于实例的学习方法,通过计算新样本与训练集中每个样本的距离,然后选取最近的k个邻居进行多数表决或加权平均等方式进行分类。

4. 支持向量机(Support Vector Machine, SVM):虽然SVM的理论较为复杂,但在C语言中也可以实现基本的线性SVM分类器,通过构建最大边距超平面来划分不同类别的数据。

5. 逻辑回归(Logistic Regression):逻辑回归是一种广义线性模型,常用于二分类问题。

在C语言中,可以通过优化算法(如梯度下降法)求解模型参数。

6. ABC分类算法(Activity-Based Costing Classification):ABC分类算法主要用于库存管理和运营管理,根据物品的价值和使用频率将其分为A、B、C三类,以便进行不同的管理策略。

7. 神经网络(Artificial Neural Networks, ANN):虽然神经网络的实现通常较为复杂,但在C语言中也可以实现简单的前馈神经网络用于分类任务。

在实现这些算法时,需要注意数据预处理、模型训练、模型评估等步骤,并且可能需要使用到一些数值计算库,如BLAS和LAPACK,或者专门的机器学习库,如LibSVM和OpenCV等。

同时,由于C语言的特性,代码可能会比其他高级语言(如Python或R)更为复杂和低级,但其执行效率通常更高。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

六种常用算法一、有条不紊——递推法破解难题问:“我对数据结构有了一定了解,但还是不太懂程序。

从经典公式“程序=算法+数据结构”得知,是因为不了解算法。

能不能介绍几种简单的算法,当然从最容易懂的那种开始了?”答:“算法就是能够证明正确的解题步骤,算法有许多种,最简单的无非下面的六种:递推法、贪心法、列举法、递归法、分治法和模拟法。

刚听名字挺吓人的,其实有好多程序我们平常都见过。

这些算法当中,最最简单的莫过于递推算法了。

下面举例说明。

”1、什么是递推法递推法这种解题方法其实在我们编程的过程中用的很多,只不过没有将其上升到理论的高度罢了。

所谓递推法,就是找出和时间先后相联系或和数的大小相联系的步骤,上一步和下一步和数字的增大或减小有一定的联系。

我们要么从前向后(或从小到大)推导,也可从后向前(或从大到小)推导。

由此得出两种推导方法:顺推法和倒推法。

请看下面的示例。

示例:猴子分食桃子:五只猴子采得一堆桃子,猴子彼此约定隔天早起后再分食。

不过,就在半夜里,一只猴子偷偷起来,把桃子均分成五堆后,发现还多一个,它吃掉这桃子,并拿走了其中一堆。

第二只猴子醒来,又把桃子均分成五堆后,还是多了一个,它也吃掉这个桃子,并拿走了其中一堆。

第三只,第四只,第五只猴子都依次如此分食桃子。

那么桃子数最少应该有几个呢?编程简析:怎样编程呢?先要找一下第N只猴子和其面前桃子数的关系。

如果从第1只开始往第5只找,不好找,但如果思路一变,从第N到第1去,可得出下面的推导式:第N只猴第N只猴前桃子数目5 s5=x4 s4=s5*5/4+13 s3=s4*5/4+12 s2=s3*5/4+11 s1=s2*5/4+1s1即为所求。

上面的规律中只要将s1-s5的下标去掉:s=xs=s*5/4+1s=s*5/4+1s=s*5/4+1s=s*5/4+1所以可以用循环语句加以解决。

综观程序的整体结构,最外是一个循环,因为循环次数不定,可以使用While循环,其结束条件则是找到第一个符合条件的数。

为了做出上面while循环的结束条件,还需进一步分析上述规律的特点,要符合题目中的要求,s1-s4四个数必须全部为整数,这个可作为条件。

具体实现请参看源程序。

int peach(){ //最少最后应该是5 的倍数加1但同时又是4 的倍数, 从16 起加int k = 0,s = 0, x = 16,i = 0;while( k< 4){k = 0;s = x;for(i=4; i>=1; i--){if((s == (s/4)*4) && (s == ((s/5)*5 + 1))) //C 的整除判断{// 计一次数k++;printf("value s:%d k:%d i:%d\n", s, k, i);}s = (s/4)*5 + 1;}x += 5;}return s;}二、稳扎稳打——贪心法破解难题问:“算法除了递推法,该轮到贪心法了吧,从字面上理解,这种方法有些贪得无厌还是…?”答:“基本算法中的递推法是我们最常使用的,贪心法是另一种有意思的算法。

贪心法不仅仅是贪婪,而且是每一步都贪婪!下面举例说明。

”1、什么是贪心法贪心法就是做一种目前最贪婪的行动,一步步解决问题。

贪心法和递推法有相似之外,也是从问题的某一个初始解出发,向给定的目标递推,但不同的是每一步不是依据某一个固定的递推式,而是做一个当时看似最佳的贪心选择,不断地将问题归结为更小的相似的问题。

示例:删数问题链盘输入一个高精度的数N,去掉任意S个数字后剩下的数字按原左右次序组成一个新的正整数,编程对于给定的N和S,寻找一种方案使得剩下的数字组成的新数最小。

为了便于操作,将N做为字符串的形式输入,可以使用尽可能逼近目标的贪心算法来完成,删数的过程中是一个一个进行删除的,为了保证最后得到的数最小,每一步总是要删除使剩下的数最小的数字。

之所以做出这样贪心的选择,是因为删S个数字的最优解,包含了删除一个数字的子问题的最优解。

为了实现上述目的,我们可以进行S次选择,每次都选择N中最大的数字,此数字选择后将不再参与下次的选择。

2、小结:这就是有趣的贪心算法,说是贪得无厌可以,说是守住当前的既得利益,以此为基础,再稳扎稳打地进行下一步也行!三、滴水不漏——列举法破解难题问:“列举法是种什么样子的算法呢?”答:“列举法是比贪心法还要贪得多的算法,列举法也是一种比较笨但却很有效的算法,他想要的东东,一种情况他都不想落下,大有宁可错杀一千,不可放过一个的阵势。

下面举例说明。

”1、什么是列举法列举是针对问题所有的可能一一查看是不是符合条件,有些“宁肯错杀一千,不可放过一个”的作风。

下面的老题最能说明这种情况。

示例:百钱买百鸡:公鸡3元每只,母鸡5元每只,小鸡1元3只,一百元钱买一百只鸡。

请求出公鸡,母鸡和小鸡的数目。

编程简析我们做最极端的假设,公鸡可能是0-100,母鸡也可能是0-100,小鸡还可能是0-100,将这三种情况用循环套起来,那就是1000000种情况。

这就是列举法。

为了将题目再简化一下,我们还可以对上述题目进行一下优化处理:假设公鸡数为x,母鸡数为y,则小鸡数是100-x-y,也就有了下面的方程式:3*x+5*y+(100-x-y)/3=100从这个方程式中,我们不难看出大体的情况:公鸡最多有33只,最少是没有,即x的范围是0-33;母鸡最多20只,最少0只,即母鸡的范围是0-20;有了公鸡母鸡,小鸡数自然就是100-x-y只。

可能的方案一共有34*21种,在这么多的方案中,可能有一种或几种正好符合相等的条件。

电脑怎样工作呢?计算机事实上就是将上述34*21种方案全部过滤一遍,找出符合百钱买百鸡条件的(也即上式),只要符合,这就是我们要的输出结果。

程序实现:我们怎样将这34*21种方案罗列出呢?这么多的方案,最好的办法是还是用循环。

可用循环和循环的嵌套,一个关于公鸡数和一个关于母鸡数的循环套起来,就能将所有的方案都遍历。

后面的问题成了怎样判断哪一个方案是我们寻找的符合条件和方案呢?只能根据百钱买百鸡了,即3*x+5*y+(100-x-y)/3=100作为条件,在条件成立的一方输出x,y,和100-x-y的值就行了,这是分支要解决的问题,程序的整体结构有了,两个嵌套循环中套分支。

2、小结这就是列举法,将可能的情况一网打尽;不过在应用过程中,我们最好还是做些优化,不然,要浪费好多没必要浪费的时间。

四、镜里照镜——递归法破解难题问:“前几种办法的确名如其法,比较笨。

有没有比较潇洒一点的算法?递归属不属于些类算法呀?”答:“递归一种非常奇妙和美妙的算法形式,奇妙美妙的背后是比较难理解。

但用起来却异常简洁。

”1、什么是递归说白了递归就象我们讲的那个故事:山上有座庙,庙里有个老和尚,老和尚在讲故事,它讲的故事是:山上有座庙,庙里有个老和尚,老和尚在讲故事,它讲的故事是:……也就是直接或间接地调用了其自身。

就象上面的故事那样,故事中包含了故事本身。

因为对自身进行调用,所以需对程序段进行包装,也就出现了函数。

函数的利用是对数学上函数定义的推广,函数的正确运用有利于简化程序,也能使某些问题得到迅速实现。

对于代码中功能性较强的、重复执行的或经常要用到的部分,将其功能加以集成,通过一个名称和相应的参数来完成,这就是函数或子程序,使用时只需对其名字进行简单调用就能来完成特定功能。

函数又可分为自定义的和系统附带的,但不管是自定义的还是系统的,他们都对相应的功能进行了封装,以利于我们经常性地使用。

例如我们的对一个小数取整数INT()函数,不论什么样的小数,往()中一放,将来得到的值就自动将小数去除了。

函数执行完将返回一个值,当然这个值可以是各种类型的,子程序仅仅执行一个过程,不返回数值。

函数和子程序是执行递归的干将。

示例:小猴吃枣:小猴第一天摘下若干枣子,当即吃掉了一半,不过瘾又多吃了一个;第二天吃了剩下的一半又多吃了一个;以后每一天都吃了前一天剩下的一半多一个。

到第十天小猴再想吃时,见到只剩下一只枣子了。

问第一天这堆枣子有多少?从上题中我们可看到一个令人欣喜的规律,第十天为1,第一到第九天中后一天与1的和的两倍与前一天相等。

2、小结函数和子程序是程序瘦身计划的一部分,通过它们可以使程序中的代码适当减肥,长度维持在一个更合理的位置。

这种作用和循环的瘦身作用一起,使一个执行很长的代码可以变得很简洁。

这也更适合我们利用计算机作为工具的目的:人类做尽量少的工作,计算机仍能解决原先的问题。

另一个奇妙之处是:他们创造了递归!五、各个击破——分治法破解难题问:“问题不能一下子解决,难道不能分开解决吗,有没有算法能实现各个击破以求解决问题呢?”答:“可以的,通过各个击破的方法解决问题的算法叫做分治法。

下面我们通过示例来看一下。

”1、什么是分治法为了解决一个问题,算法有时需不止一次地对自身进行调用,来解决相类似的子问题。

这样的算法通常称为分治法:将原问题分成n个规模较小而结构与原问题相似的子问题。

下面通过排序的一种方法来看一下。

希尔排序即是采用分治法来进行排序的,又称做缩小增量排序,其思想是:把已经在数组中的数据按下标的一定增量分组,对分出的每一小组使用插入排序,随着增量逐渐减小,所分成的组包含的数据越来越多,直到减小到1时,整个数据合并成一组,构成一组有序数,则完成排序。

示例:十个数,从大到小排序。

数据放在一个数组a(10)中,假如原始数据如下:70. 53. 57. 28. 30. 77. 1. 76. 81. 70,则排序过程如下:增量值5: 77. 53. 76. 81. 70. 70. 1. 57. 28. 30.2: 77. 81. 76. 70. 70. 57. 28. 53. 1. 30.1: 81. 77. 76. 70. 70. 57. 53. 30. 28. 1.其中上面三个增量值对应的都是以该增量完成本轮排序后的情况,看增量为5时要和原始数据比较,增量为2的情况要和5比较,1要和2比较,这样其中的规律就清楚了。

2、小结在进行希尔排序时,需注意增量序列的取值方法,并且使这些序列中的值没有除1之外的公因子,且最后一个增量值必须为1。

能解决问题的办法都是好办法,问题不一定整体解决才好。

这就是分治的思想。

六、乱打误撞——模拟法破解难题问:“电脑解决确定问题可做到手到擒来,对于电脑中实现一个不确定的问题,例如彩票或抽奖,怎样做呢?”答:“算法的美妙在于其准确和确定,而另有一种价值则在于其不确定,象我们的抽奖程序和彩票程序。

确定的问题电脑可以处理,不确定的问题电脑也能处理,随机函数就是实现电脑中不确定事件的重要砝码。

下面我们通过示例来看一下。

相关文档
最新文档