10个重要的算法C语言实现源代码:拉格朗日,牛顿插值,高斯,龙贝格,牛顿迭代,牛顿-科特斯,雅克比,秦九昭,幂法,高斯塞德尔
1.拉格朗日插值多项式,用于离散数据的拟合
1#include
2 #include
3 #include
4float lagrange(float *x,float *y,float xx,int n) /*拉格朗日插值算法*/
5 { int i,j;
6float *a,yy=0.0; /*a作为临时变量,记录拉格朗日插值多项式*/
7 a=(float *)malloc(n*sizeof(float));
8for(i=0;i<=n-1;i++)
9 { a[i]=y[i];
10for(j=0;j<=n-1;j++)
11if(j!=i) a[i]*=(xx-x[j])/(x[i]-x[j]);
12 yy+=a[i];
13 }
14 free(a);
15return yy;
16}
17main()
18{ int i,n;
19float x[20],y[20],xx,yy;
20 printf("Input n:");
21 scanf("%d",&n);
22if(n>=20) {printf("Error!The value of n must in (0,20)."); getch();return1;}
23if(n<=0) {printf("Error! The value of n must in (0,20)."); getch(); return1;}
25 { printf("x[%d]:",i);
26 scanf("%f",&x[i]);
27 }
28 printf("\n");
29for(i=0;i<=n-1;i++)
30 { printf("y[%d]:",i);scanf("%f",&y[i]);}
31 printf("\n");
32 printf("Input xx:");
33 scanf("%f",&xx);
34 yy=lagrange(x,y,xx,n);
35 printf("x=%f,y=%f\n",xx,yy);
36 getch();
37}
38
2.牛顿插值多项式,用于离散数据的拟合
1#include
2#include
3#include
4void difference(float *x,float *y,int n)
5{ float *f;
6int k,i;
7 f=(float *)malloc(n*sizeof(float));
8for(k=1;k<=n;k++)
9 { f[0]=y[k];
11 f[i+1]=(f[i]-y[i])/(x[k]-x[i]);
12 y[k]=f[k];
13 }
14return;
15}
16main()
17{ int i,n;
18float x[20],y[20],xx,yy;
19 printf("Input n:");
20 scanf("%d",&n);
21if(n>=20) {printf("Error! The value of n must in (0,20)."); getch(); return1;}
22if(n<=0) {printf("Error! The value of n must in (0,20).");getch(); return1;} 23for(i=0;i<=n-1;i++)
24 { printf("x[%d]:",i);
25 scanf("%f",&x[i]);
26 }
27 printf("\n");
28for(i=0;i<=n-1;i++)
29 { printf("y[%d]:",i);scanf("%f",&y[i]);}
30 printf("\n");
31 difference(x,(float *)y,n);
32 printf("Input xx:");
33 scanf("%f",&xx);
34 yy=y[20];
35for(i=n-1;i>=0;i--) yy=yy*(xx-x[i])+y[i];
36 printf("NewtonInter(%f)=%f",xx,yy);
37 getch();
38}
39
3.高斯列主元消去法,求解其次线性方程组
1#include
2#include
3#define N 20
4int main()
5{ int n,i,j,k;
6int mi,tmp,mx;
7float a[N][N],b[N],x[N];
8 printf("\nInput n:");
9 scanf("%d",&n);
10if(n>N)
11 { printf("The input n should in(0,N)!\n");
12 getch();
13return1;
14 }
15if(n<=0)
16 { printf("The input n should in(0,N)!\n");
17 getch();
18return1;
19 }
20 printf("Now input a(i,j),i,j=0%d:\n",n-1); 21for(i=0;i 22 { for(j=0;j 23 scanf("%f",&a[i][j]);} 24 printf("Now input b(i),i,j=0%d:\n",n-1); 25for(i=0;i 26 scanf("%f",&b[i]); 27for(i=0;i 28 { for(j=i+1,mi=i,mx=fabs(a[i][j]);j 30 { mi=j; 31 mx=fabs(a[j][i]); 32 } 33if(i 34 { tmp=b[i];b[i]=b[mi];b[mi]=tmp; 35for(j=i;j 36 { tmp=a[i][j]; 37 a[i][j]=a[mi][j]; 38 a[mi][j]=tmp; 39 } 40 } 41for(j=i+1;j 42 { tmp=-a[j][i]/a[i][i]; 43 b[j]+=b[i]*tmp; 44for(k=i;k 45 a[j][k]+=a[i][k]*tmp; 46 } 47 } 48 x[n-1]=b[n-1]/a[n-1][n-1]; 49for(i=n-2;i>=0;i--) 50 { x[i]=b[i]; 51for(j=i+1;j 52 x[i]-=a[i][j]*x[j]; 53 x[i]/=a[i][i]; 54 } 55for(i=0;i 56 printf("Answer:\n x[%d]=%f\n",i,x[i]); 57 getch(); 58return0; 59} 60 61 62#include 63#include 64#define NUMBER 20 65#define Esc 0x1b 66#define Enter 0x0d 67 68float A[NUMBER][NUMBER+1] ,ark; 69int flag,n; 70exchange(int r,int k); 71float max(int k); 72message(); 73 74main() 75{ 76float x[NUMBER]; 77int r,k,i,j; 78char celect; 79 clrscr(); 80 81 printf("\n\nUse Gauss."); 82 printf("\n\n1.Jie please press Enter."); 83 printf("\n\n2.Exit press Esc."); 84 celect=getch(); 85if(celect==Esc) 86 exit(0); 87 printf("\n\n input n="); 88 scanf("%d",&n); 89 printf(" \n\nInput matrix A and B:"); 90for(i=1;i<=n;i++) 91 { 92 printf("\n\nInput a%d1--a%d%d and b%d:",i,i,n,i); 93 94for(j=1;j<=n+1;j++) scanf("%f",&A[i][j]); 95 } 96for(k=1;k<=n-1;k++) 97 { 98 ark=max(k); 99if(ark==0) 100 { 101 printf("\n\nIt's wrong!");message(); 102 } 103else if(flag!=k) 104 exchange(flag,k); 105for(i=k+1;i<=n;i++) 106for(j=k+1;j<=n+1;j++) 107 A[i][j]=A[i][j]-A[k][j]*A[i][k]/A[k][k]; 108 } 109 x[n]=A[n][n+1]/A[n][n]; 110for( k=n-1;k>=1;k--) 111 { 112float me=0; 113for(j=k+1;j<=n;j++) 114 { 115 me=me+A[k][j]*x[j]; 116 } 117 x[k]=(A[k][n+1]-me)/A[k][k]; 118 } 119for(i=1;i<=n;i++) 120 { 121 printf(" \n\nx%d=%f",i,x[i]); 122 } 123 message(); 124} 125 126exchange(int r,int k) 127{ 128int i; 129for(i=1;i<=n+1;i++) 130 A[0][i]=A[r][i]; 131for(i=1;i<=n+1;i++) 132 A[r][i]=A[k][i]; 133for(i=1;i<=n+1;i++) 134 A[k][i]=A[0][i]; 135} 136 137float max(int k) 138{ 139int i; 140float temp=0; 141for(i=k;i<=n;i++) 142if(fabs(A[i][k])>temp) 143 { 144 temp=fabs(A[i][k]); 145 flag=i; 146 } 147return temp; 148} 149 150message() 151{ 152 printf("\n\n Go on Enter ,Exit press Esc!"); 153switch(getch()) 154 { 155case Enter: main(); 156case Esc: exit(0); 157default:{printf("\n\nInput error!");message();} 158 } 159} 4.龙贝格求积公式,求解定积分 1#include 2#include 3#define f(x) (sin(x)/x) 4#define N 20 5#define MAX 20 6#define a 2 7#define b 4 8#define e 0.00001 9float LBG(float p,float q,int n) 10{ int i; 11float sum=0,h=(q-p)/n; 12for (i=1;i 13 sum+=f(p+i*h); 14 sum+=(f(p)+f(q))/2; 15return(h*sum); 16} 17void main() 18 { int i; 19int n=N,m=0; 20float T[MAX+1][2]; 21 T[0][1]=LBG(a,b,n); 22 n*=2; 23for(m=1;m 24 { for(i=0;i 25 T[i][0]=T[i][1]; 26 T[0][1]=LBG(a,b,n); 27 n*=2; 28for(i=1;i<=m;i++) 29 T[i][1]=T[i-1][1]+(T[i-1][1]-T[i-1][0])/(pow(2,2*m)-1); 30if((T[m-1][1] 31 { printf("Answer=%f\n",T[m][1]); getch(); 32return ; 33 } 34 } 35 } 36 5.牛顿迭代公式,求方程的近似解 1#include 2#include 3#include 4#define N 100 5#define PS 1e-5 6#define TA 1e-5 7float Newton(float (*f)(float),float(*f1)(float),float x0 ) 8{ float x1,d=0; 9int k=0; 10do 11 { x1= x0-f(x0)/f1(x0); 12if((k++>N)||(fabs(f1(x1)) 13 { printf("\nFailed!"); 14 getch(); 15 exit(); 16 } 17 d=(fabs(x1)<1?x1-x0:(x1-x0)/x1); 18 x0=x1; 19 printf("x(%d)=%f\n",k,x0); 20 } 21while((fabs(d))>PS&&fabs(f(x1))>TA) ; 22return x1; 23} 24float f(float x) 25{ return x*x*x+x*x-3*x-3; } 26float f1(float x) 27{ return3.0*x*x+2*x-3; } 28void main() 29{ float f(float); 30float f1(float); 31float x0,y0; 32 printf("Input x0: "); 33 scanf("%f",&x0); 34 printf("x(0)=%f\n",x0); 35 y0=Newton(f,f1,x0); 36 printf("\nThe root is x=%f\n",y0); 37 getch(); 38} 6. 牛顿-科特斯求积公式,求定积分 1#include 2#include 3int NC(a,h,n,r,f) 4float (*a)[]; 5float h; 6int n,f; 7float *r; 8{ int nn,i; 9float ds; 10if(n>1000||n<2) 11 { if (f) 12 printf("\n Faild! Check if 1 13return(-1); 14} 15if(n==2) 16{ *r=0.5*((*a)[0]+(*a)[1])*(h); 17return(0); 18} 19if (n-4==0) 20 { *r=0; 21*r=*r+0.375*(h)*((*a)[n-4]+3*(*a)[n-3]+3*(*a)[n-2]+(*a)[n-1]); 22return(0); 23} 24if(n/2-(n-1)/2<=0) 25nn=n; 26else 27nn=n-3; 28ds=(*a)[0]-(*a)[nn-1]; 29for(i=2;i<=nn;i=i+2) 30ds=ds+4*(*a)[i-1]+2*(*a)[i]; 31*r=ds*(h)/3; 32if(n>nn) 33*r=*r+0.375*(h)*((*a)[n-4]+3*(*a)[n-3]+3*(*a)[n-2]+(*a)[n-1]); 34return(0); 35} 36main() 37{ 38float h,r; 39int n,ntf,f; 40int i; 41float a[16]; 42printf("Input the x[i](16):\n"); 43for(i=0;i<=15;i++) 44 scanf("%d",&a[i]); 45h=0.2; 46f=0; 47ntf=NC(a,h,n,&r,f); 48if(ntf==0) 49 printf("\nR=%f\n",r); 50else 51 printf("\n Wrong!Return code=%d\n",ntf); 52 getch(); 53} 7.雅克比迭代,求解方程近似解 1#include 2#include 3#define N 20 4#define MAX 100 5#define e 0.00001 6int main() 7{ int n; 8int i,j,k; 9float t; 10float a[N][N],b[N][N],c[N],g[N],x[N],h[N]; 11 printf("\nInput dim of n:"); scanf("%d",&n); 12if(n>N) 13 { printf("Faild! Check if 0 15 {printf("Faild! Check if 0 16 printf("Input a[i,j],i,j=0…%d:\n",n-1); 17for(i=0;i 18for(j=0;j 19 scanf("%f",&a[i][j]); 20 printf("Input c[i],i=0…%d:\n",n-1); 21for(i=0;i 22scanf("%f",&c[i]); 23for(i=0;i 24for(j=0;j 25 { b[i][j]=-a[i][j]/a[i][i]; g[i]=c[i]/a[i][i]; } 26for(i=0;i 27 { for(j=0;j 28 h[j]=g[j]; 29 { for(k=0;k 30 { if(j==k) continue; h[j]+=b[j][k]*x[k]; } 31 } 32 t=0; 33for(j=0;j 34if(t 35for(j=0;j 36 x[j]=h[j]; 37if(t 38 { printf("x_i=\n"); 39for(i=0;i 40printf("x[%d]=%f\n",i,x[i]); 41 getch(); 42return0; 43 } 44 printf("after %d repeat , return\n",MAX); 45 getch(); 46return1; 47 } 48 getch(); 49} 50 8.秦九昭算法 1#include 2float qin(float a[],int n,float x) 3{ float r=0; 4int i; 5for(i=n;i>=0;i--) 6 r=r*x+a[i]; 7return r; 8} 9main() 10{ float a[50],x,r=0; 11int n,i; 12do 13 { printf("Input frequency:"); 14 scanf("%d",&n); 15 } 16while(n<1); 17 printf("Input value:"); 18for(i=0;i<=n;i++) 19 scanf("%f",&a[i]); 20 printf("Input frequency:"); 21 scanf("%f",&x); 22 r=qin(a,n,x); 23 printf("Answer:%f",r); 24 getch(); 25} 26 9.幂法 1#include 2#include 3#define N 100 4#define e 0.00001 5#define n 3 6float x[n]={0,0,1}; 7float a[n][n]={{2,3,2},{10,3,4},{3,6,1}}; 8float y[n]; 9main() 10{ int i,j,k; 11float xm,oxm; 12 oxm=0; 13for(k=0;k 14 { for(j=0;j 15 { y[j]=0; 16for(i=0;i 17 y[j]+=a[j][i]*x[i]; 18 } 19 xm=0; 20for(j=0;j 21if(fabs(y[j])>xm) xm=fabs(y[j]); 22for(j=0;j 23 y[j]/=xm; 24for(j=0;j 25 x[j]=y[j]; 26if(fabs(xm-oxm) 27 { printf("max:%f\n\n",xm); 28 printf("v[i]:\n"); 29for(k=0;k 30break; 31 } 32 oxm=xm; 33 } 34 getch(); 35} 36 10.高斯塞德尔 1#include 2#include 3#define N 20 4#define M 99 5float a[N][N]; 6float b[N]; 7int main() 8{ int i,j,k,n; 9float sum,no,d,s,x[N]; 10 printf("\nInput dim of n:"); 11 scanf("%d",&n); 12if(n>N) 13 { printf("Faild! Check if 0 15 } 16if(n<=0) 17 { printf("Faild! Check if 0 18 printf("Input a[i,j],i,j=0…%d:\n",n-1); 19for(i=0;i 20for(j=0;j 21 scanf("%f",&a[i][j]); 22 printf("Input b[i],i=0…%d:\n",n-1); 23for(i=0;i 24for(i=0;i 25 k=0; 26 printf("\nk=%dx=",k); 27for(i=0;i 28do 29 { k++; 30if(k>M){printf("\nError!\n”);getch();} 31break; 32 } 33 no=0.0; 34for(i=0;i 35 { s=x[i]; 36 sum=0.0; 37for(j=0;j 38if (j!=i) sum=sum+a[i][j]*x[j]; 39 x[i]=(b[i]-sum)/a[i][i]; 40 d=fabs(x[i]-s); 41if (no 42 } 《数据结构与算法》期末复习题 一、选择题。 1.在数据结构中,从逻辑上可以把数据结构分为 C 。 A.动态结构和静态结构B.紧凑结构和非紧凑结构 C.线性结构和非线性结构D.内部结构和外部结构 2.数据结构在计算机内存中的表示是指 A 。 A.数据的存储结构B.数据结构C.数据的逻辑结构D.数据元素之间的关系 3.在数据结构中,与所使用的计算机无关的是数据的 A 结构。 A.逻辑B.存储C.逻辑和存储D.物理 4.在存储数据时,通常不仅要存储各数据元素的值,而且还要存储 C 。 A.数据的处理方法B.数据元素的类型 C.数据元素之间的关系D.数据的存储方法 5.在决定选取何种存储结构时,一般不考虑 A 。 A.各结点的值如何B.结点个数的多少 C.对数据有哪些运算D.所用的编程语言实现这种结构是否方便。 6.以下说法正确的是 D 。 A.数据项是数据的基本单位 B.数据元素是数据的最小单位 C.数据结构是带结构的数据项的集合 D.一些表面上很不相同的数据可以有相同的逻辑结构 7.算法分析的目的是 C ,算法分析的两个主要方面是 A 。 (1)A.找出数据结构的合理性B.研究算法中的输入和输出的关系C.分析算法的效率以求改进C.分析算法的易读性和文档性 (2)A.空间复杂度和时间复杂度B.正确性和简明性 C.可读性和文档性D.数据复杂性和程序复杂性 8.下面程序段的时间复杂度是O(n2) 。 s =0; for( I =0; i 一、基本算法 1.交换(两量交换借助第三者) 例1、任意读入两个整数,将二者的值交换后输出。 main() {int a,b,t; scanf("%d%d",&a,&b); printf("%d,%d\n",a,b); t=a; a=b; b=t; printf("%d,%d\n",a,b);} 【解析】程序中加粗部分为算法的核心,如同交换两个杯子里的饮料,必须借助第三个空杯子。 假设输入的值分别为3、7,则第一行输出为3,7;第二行输出为7,3。 其中t为中间变量,起到“空杯子”的作用。 注意:三句赋值语句赋值号左右的各量之间的关系! 【应用】 例2、任意读入三个整数,然后按从小到大的顺序输出。 main() {int a,b,c,t; scanf("%d%d%d",&a,&b,&c); /*以下两个if语句使得a中存放的数最小*/ if(a>b){ t=a; a=b; b=t; } if(a>c){ t=a; a=c; c=t; } /*以下if语句使得b中存放的数次小*/ if(b>c) { t=b; b=c; c=t; } printf("%d,%d,%d\n",a,b,c);} 2.累加 累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而实现累加功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为0。例1、求1+2+3+……+100的和。 main() {int i,s; s=0; i=1; while(i<=100) {s=s+i; /*累加式*/ i=i+1; /*特殊的累加式*/ } printf("1+2+3+...+100=%d\n",s);} 【解析】程序中加粗部分为累加式的典型形式,赋值号左右都出现的变量称为累加器,其中“i = i + 1”为特殊的累加式,每次累加的值为1,这样的累加器又称为计数器。 2008-02-18 18:48 【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2.程序源代码: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&i!=j&&j!=k) /*确保i、j、k三位互不相同*/ printf("%d,%d,%d\n",i,j,k); } } ============================================================== 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数? 1.程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2.程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf("%ld",&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i<=100000) 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 } 3.素数的判断: /*方法一*/ for (t=1,i=2;i 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 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 60.题目:古典问题:有一对兔子,从出生后第3个月 起每个月都生一对兔子,小兔 子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总 数 为多少? _________________________________________________________________ _ 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... _________________________________________________________________ __ 程序源代码: main() { long f1,f2; int i; f1=f2=1; for(i=1;i<=20;i++) { printf("%12ld %12ld",f1,f2); if(i%2==0) printf("\n");/*控制输出,每行四个*/ f1=f1+f2;/*前两个月加起来赋值给第三个月*/ f2=f1+f2;/*前两个月加起来赋值给第三个月*/ } } 上题还可用一维数组处理,you try! 61.题目:判断101-200之间有多少个素数,并输出所有素数。 _________________________________________________________________ _ 1 程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被 整 除,则表明此数不是素数,反之是素数。 _________________________________________________________________ __ 程序源代码: #include "math.h" main() { int m,i,k,h=0,leap=1; /* ===================================================================== ======== 相关知识介绍(所有定义只为帮助读者理解相关概念,并非严格定义): 1、稳定排序和非稳定排序 简单地说就是所有相等的数经过某种排序方法后,仍能保持它们在排序之前的相对次序,我们就 说这种排序方法是稳定的。反之,就是非稳定的。 比如:一组数排序前是a1,a2,a3,a4,a5,其中a2=a4,经过某种排序后为 a1,a2,a4,a3,a5, 则我们说这种排序是稳定的,因为a2排序前在a4的前面,排序后它还是在a4的前面。假如变成a1,a4, a2,a3,a5就不是稳定的了。 2、内排序和外排序 在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序; 在排序过程中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序。 3、算法的时间复杂度和空间复杂度 所谓算法的时间复杂度,是指执行算法所需要的计算工作量。 一个算法的空间复杂度,一般是指执行这个算法所需要的内存空间。 ===================================================================== =========== */ /* ================================================ 功能:选择排序 输入:数组名称(也就是数组首地址)、数组中元素个数 ================================================ */ /* ==================================================== 算法思想简单描述: C语言常用算法归纳 应当掌握的一般算法 一、基本算法: 交换、累加、累乘 二、非数值计算常用经典算法: 穷举、排序(冒泡,选择)、查找(顺序即线性) 三、数值计算常用经典算法: 级数计算(直接、简接即递推)、一元非线性方程求根(牛顿迭代法、二分法)、定积分计算(矩形法、梯形法) 四、其他: 迭代、进制转换、矩阵转置、字符处理(统计、数字串、字母大小写转换、加密等)、整数各数位上数字的获取、辗转相除法求最大公约数(最小公倍数)、求最值、判断素数(各种变形)、数组元素的插入(删除)、二维数组的其他典型问题(方阵的特点、杨辉三角形) 详细讲解 一、基本算法 1.交换(两量交换借助第三者) 例1、任意读入两个整数,将二者的值交换后输出。 main() { int a,b,t; scanf("%d%d",&a,&b); printf("%d,%d\n",a,b); t=a; a=b; b=t; printf("%d,%d\n",a,b); } 【解析】程序中加粗部分为算法的核心,如同交换两个杯子里的饮料,必须借助第三个空杯子。 假设输入的值分别为3、7,则第一行输出为3,7;第二行输出为7,3。 其中t为中间变量,起到“空杯子”的作用。 注意:三句赋值语句赋值号左右的各量之间的关系! 【应用】 例2、任意读入三个整数,然后按从小到大的顺序输出。 main() { int a,b,c,t; scanf("%d%d%d",&a,&b,&c); /*以下两个if语句使得a中存放的数最小*/ if(a>b){ t=a; a=b; b=t; } if(a>c){ t=a; a=c; c=t; } /*以下if语句使得b中存放的数次小*/ if(b>c) { t=b; b=c; c=t; } printf("%d,%d,%d\n",a,b,c); } 2.累加 累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而实现累加功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为0。 例1、求1+2+3+……+100的和。 main() { int i,s; s=0; i=1; while(i<=100) { s=s+i; /*累加式*/ i=i+1; /*特殊的累加式*/ } printf("1+2+3+...+100=%d\n",s); } 【解析】程序中加粗部分为累加式的典型形式,赋值号左右都出现的变量称为累加器,其中“i = i + 1”为特殊的累加式,每次累加的值为1,这样的累加器又称为计数器。 3.累乘 C程序设计的常用算法 算法(Algorithm):计算机解题的基本思想方法和步骤。算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么数据(输入什么数据、输出什么结果)、采用什么结构、使用什么语句以及如何安排这些语句等。通常使用自然语言、结构化流程图、伪代码等来描述算法。 一、简单数值类算法 此类问题都要使用循环,要注意根据问题确定循环变量的初值、终值或结束条件,更要注意用来表示计数、和、阶乘的变量的初值。 1、求阶乘:n!=1*2*384…..*n; n!= n*(n-1)!= 下列程序用于求n的阶乘.在累乘之前,一定要将用于存放乘积的变量的值初始化为1. long func(int n) { int i; long t=1; for(i=2;i<=n;i++) t*=i; return t; } printf("\n"); } main() { int n; scanf("%d", &n); printf("n!=%ld\n", fac(n)); } 2、整数拆分问题:把一个整数各个位上的数字存到数组中 #define N 4 /* N代表整数位数*/ viod split(int n, int a[ ]) /* 1478: a[ 3]=8, a[2 ]=7, a[1 ]=4…*/ {int i; for(i=N-1;i!=0; i--) { a[i]=n%10; n=n/10; } } main() {int i,m=1478,b[N-1]; split(m, b); for(i=0;i<4; i++) printf(“%5d”, b[i]); 八、常用算法 (一)考核知识要点 1.交换、累加、累乘、求最大(小)值 2.穷举 3.排序(冒泡、插入、选择) 4.查找(顺序、折半) 5.级数计算(递推法) 6.一元方程求解(牛顿迭代法、二分法) 7.矩阵(转置) 8.定积分计算(矩形法、梯形法) 9.辗转相除法求最大公约数、判断素数 10.数制转换 (二)重点、难点精解 教材中给出的算法就不再赘述了。 1.基本操作:交换、累加、累乘 1)交换 交换算法的要领是“借助第三者”(如同交换两个杯子里的饮料,必须借助第三个空杯子)。例如,交换两个整型变量里的数值:int a=7,b=9,t; t=a; a=b; b=t; (不借助第三者,也能交换两个整型变量里的数值,但不通用,只是一个题目而已。 例如:int a=7,b=9; a=a+b; b=a-b; a=a-b;) 2)累加 累加算法的要领是形如“s=s+A”的累加式,此式必须出现在循环中才能被反复执行,从而实现累加功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为0。 3)累乘 累乘算法的要领是形如“s=s*A”的累乘式,此式必须出现在循环中才能被反复执行,从而实现累乘功能。“A”通常是有规律变化的表达式,s在进入循环前必须获得合适的初值,通常为1。 2.非数值计算常用经典算法 1)穷举法 也称为“枚举法”,即将可能出现的各种情况一一测试,判断是否满足条件,一般采用循环来实现。 例如,用穷举法输出“将1元人民币兑换成1分、2分、5分硬币”的所有方法。 main() {int y,e,w; for(y=0;y<=100;y++) for(e=0;e<=50;e++) for(w=0;w<=20;w++) 《数据结构与算法》实验报告 一、需求分析 问题描述:在教科书中,各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。 基本要求: (l)对以下6种常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。 (2)待排序表的表长不小于100000;其中的数据要用伪随机数程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字的移动次数(关键字交换计为3次移动)。(3)最后要对结果作简单分析,包括对各组数据得出结果波动大小的解释。数据测试:二.概要设计 1.程序所需的抽象数据类型的定义: typedef int BOOL; //说明BOOL是int的别名 typedef struct StudentData { int num; //存放关键字} Data; typedef struct LinkList { int Length; //数组长度 Data Record[MAXSIZE]; //用数组存放所有的随机数 } LinkList int RandArray[MAXSIZE]; //定义长度为MAXSIZE的随机数组void RandomNum() //随机生成函数 void InitLinkList(LinkList* L) //初始化链表 BOOL LT(int i, int j,int* CmpNum) //比较i和j 的大小 void Display(LinkList* L) //显示输出函数 void ShellSort(LinkList* L, int dlta[], int t,int* CmpNum, int* ChgNum) //希尔排序 void QuickSort (LinkList* L, int* CmpNum, int* ChgNum) //快速排序 void HeapSort (LinkList* L, int* CmpNum, int* ChgNum) //堆排序 void BubbleSort(LinkList* L, int* CmpNum, int* ChgNum) //冒泡排序 void SelSort(LinkList* L, int* CmpNum, int* ChgNum) //选择排序 void Compare(LinkList* L,int* CmpNum, int* ChgNum) //比较所有排序 2 .各程序模块之间的层次(调用)关系: 打印金字塔和三角形 使用 * 建立三角形 * * * * * * * * * * * * * * * 源代码: #include C语言常考算法归纳 应当掌握的一般算法 一、基本算法: 交换、累加、累乘 二、非数值计算常用经典算法: 穷举、排序(冒泡,选择,插入,归并)、查找(顺序即线性,折半) 三、数值计算常用经典算法: 级数计算(直接、简接即递推)、一元非线性方程求根(牛顿迭代法、二分法)、定积分计算(矩形法、梯形法)、矩阵转置、矩阵相乘 四、其他: 迭代、进制转换、字符处理(统计、数字串、字母大小写转换、加密等)、整数各数位上数字的获取、辗转相除法求最大公约数(最小公倍数)、求最值、判断素数(各种变形)、数组元素的插入(删除)、二维数组的其他典型问题(方阵的特点、杨辉三角形) 详细讲解 一、基本算法 1.交换(两量交换借助第三者) 例1、任意读入两个整数,将二者的值交换后输出。 main() {int a,b,t; scanf("%d%d",&a,&b); printf("%d,%d\n",a,b); t=a; a=b; b=t; printf("%d,%d\n",a,b);} 【解析】程序中加粗部分为算法的核心,如同交换两个杯子里的饮料,必须借助第三个空杯子。 假设输入的值分别为3、7,则第一行输出为3,7;第二行输出为7,3。 其中t为中间变量,起到“空杯子”的作用。 注意:三句赋值语句赋值号左右的各量之间的关系! 【应用】 例2、任意读入三个整数,然后按从小到大的顺序输出。 main() {int a,b,c,t; scanf("%d%d%d",&a,&b,&c); /*以下两个if语句使得a中存放的数最小*/ if(a>b){ t=a; a=b; b=t; } if(a>c){ t=a; a=c; c=t; } /*以下if语句使得b中存放的数次小*/ if(b>c) { t=b; b=c; c=t; } dijkstra 迪杰斯特拉单源最短路径,必须给出源点V0 邻接矩阵cost存储有向网;使用一个集合S存储那些已经找到最短路径的顶点,初始只包含源点v0;设置两个数组dis[n]、pre[n],数组dist记录从源点到其余各顶点当前的最短路径,初始时dis[i]=cost[v0][i];数组pre存储最短路径上终点v之前的那个顶点,初始时pre[i]=v0;具体过程是从v-s中找一个w,使dis[w]最小,将w加入到s中,然后以w 作为新考虑的中间点,对s集合以外的每个顶点I,比较dis[w]+cost[w][j]与dis[i]的大小,若前者小于后者,表明加入了新的中间点w之后,从v0通过w到i的路径比原来的短,应该用它替换dis[i]的原值,使dis[i]始终保持目前为止最短的路径,若dis[w]+cost[w][j] 快速幂取模算法 在网站上一直没有找到有关于快速幂算法的一个详细的描述和解释,这里,我给出快速幂算法的完整解释,用的是C 语言,不同语言的读者只好换个位啦,毕竟读C 的人较多~ 所谓的快速幂,实际上是快速幂取模的缩写,简单的说,就是快速的求一个幂式的模(余)。在程序设计过程中,经常要去求一些大数对于某个数的余数,为了得到更快、计算范围更大的算法,产生了快速幂取模算法。[有读者反映在讲快速幂部分时有点含糊,所以在这里对本文进行了修改,作了更详细的补充,争取让更多的读者一目了然] 我们先从简单的例子入手:求c a b mod = 几。 算法1.首先直接地来设计这个算法: int ans = 1; for (int i = 1;i<=b;i++) { ans = ans * a; } ans = ans % c; 这个算法的时间复杂度体现在for 循环中,为O (b ).这个算法存在着明显的问题,如果a 和b 过大,很容易就会溢出。 那么,我们先来看看第一个改进方案:在讲这个方案之前,要先有这样一个公式: c c a c a b b mod )mod (mod =.这个公式大家在离散数学或者数论当中应该学过,不过这里为了方便大家的阅读,还是给出证明: 引理1: c c b c a c de c de c dk te tkc c e kc d tc c ab e kc b e c b d tc a d c a c c b c a c ab mo d )]mod ()mod [(mod mod ))((mod ))((mod mod mod mod )]mod ()mod [(mod )(:2?==+++=++=+=?=+=?=?=证明: 公式 上面公式为下面公式的引理,即积的取余等于取余的积的取余。 c a c c a c c c a c c a c c a c a b b b b b b mo d mod ])mod [() (mod ])mod )mod [((mod ])mod [(mod )mod (mod ===由上面公式的迭代证明:公式: 证明了以上的公式以后,我们可以先让a 关于c 取余,这样可以大大减少a 的大小, 于是不用思考的进行了改进: 算法2: int ans = 1; a = a % c; //加上这一句 C 程序设计的常用算法 算法( Algorithm ):计算机解题的基本思想方法和步骤。算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么数据(输入什么数据、输出什么结果)、采用什么结构、使用什么语句以及如何安排这些语句等。通常使用自然语言、结构化流程图、伪代码等来描述算法。 一、简单数值类算法 此类问题都要使用循环,要注意根据问题确定循环变量的初值、终值或结束条件,更要注意用来表示计数、和、阶乘的变量的初值。 1、求阶乘:n!=1*2*384 …..*n; n!= n*(n-1)!= 下列程序用于求n 的阶乘.在累乘之前,一定要将用于存放乘积的变量的值初始化为1. long func(int n) { int i; long t=1; for(i=2;i<=n;i++) t*=i; return t; } printf("\n"); } main() { int n; scanf("%d", &n); printf("n!=%ld\n", fac(n)); } 2、整数拆分问题:把一个整数各个位上的数字存到数组中 #define N 4 /* N 代表整数位数*/ viod split(int n, int a[ ] ) /* 1478: a[ 3]=8, a[2 ]=7, a[1 ]=4 …*/ {int i; for(i=N-1;i!=0; i--) { a[i]=n%10; n=n/10; } } main() {int i,m=1478,b[N-1]; split(m, b) ; for(i=0;i<4; i++) printf( “%5d”, b[i]); } 3、求整数的因子之和12=1*2*3*4 long factor(int n) {int i; long sum=0; C 语言经典算法100 例(1) (2007-08-15 15:09:22) C 语言编程经典100 例 【程序1】 题目:有1、2、3、4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1. 程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。 2. 程序源代码: main() { int i,j,k; printf( “\n “); for(i=1;i 〈5;i++) /* 以下为三重循环*/ for(j=1;j 〈5;j++) for (k=1;k 〈5;k++) { if (i!=k&&i!=j&&j!=k) /* 确保i 、j 、k 三位互不相同*/ printf( “ %d,%d,%d\n“,i,j,k); } } 【程序2】 题目:企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%利润高于10万元,低于20万元时, 低于10万元的部分按10%提成,高于10 万元的部分,可可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40 万到60 万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60 万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按19提成,从键盘输入当月利润I,求应发放奖金总数? 1. 程序分析:请利用数轴来分界,定位。注意定义时需把奖金定义成长整型。 2. 程序源代码: main() { long int i; int bonus1,bonus2,bonus4,bonus6,bonus10,bonus; scanf( “%ld“ ,&i); bonus1=100000*0.1;bonus2=bonus1+100000*0.75; bonus4=bonus2+200000*0.5; bonus6=bonus4+200000*0.3; bonus10=bonus6+400000*0.15; if(i 〈=100000) bonus=i*0.1; else if(i 〈=200000) bonus=bonus1+(i-100000)*0.075; else if(i 〈=400000) bonus=bonus2+(i-200000)*0.05; else if(i 〈=600000) bonus=bonus4+(i-400000)*0.03; else if(i 〈=1000000) bonus=bonus6+(i-600000)*0.015; else bonus=bonus10+(i-1000000)*0.01; printf( “ bonus=%d“ ,bonus);数据结构与算法C语言版期末复习题
非常全的C语言常用算法
C语言经典算法100例(1---30)
C语言常用算法集合
最新C语言常用算法集合汇总
c语言经典算法100例
C语言常用排序算法
最新C语言常用算法归纳
C语言常用算法程序汇总
(整理)C语言常用算法.
数据结构(C语言版)实验报告-(内部排序算法比较)
C语言常用算法2
C语言常考算法归纳
数据结构C语言版常用算法思想汇总
快速幂算法C语言版(超详细)
C语言常用算法程序汇总
C语言经典算法100例