还剩22页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言常用算法归纳C应当掌握的一般算法
一、基本算法互换、累加、累乘
二、非数值计算常用经典算法穷举、排序(冒泡,选择)、查找(次序即线性)
三、数值计算常用经典算法级数计算(直接、简接即递推)、一元非线性方程求根(牛顿迭代法、二分法)、定积分计算(矩形法、梯形法)U!迭代、进制转换、矩阵转置、字符处理(记录、数字串、字母大小写转换、加密等)、整数各数位上数字的获取、辗转相除法求最大公约数(最小公倍数)、求最值、判断素数(多种变形)、数组元素的插入(删除)、二维数组的其他经典问题(方阵的特点、杨辉三角形)详细讲解
一、基本算法互换(两量互换借助第三者)
1.例
1、任意读入两个整数,将两者的值互换后输出()main{int a,b,t;scanf(n%d%dn,a b);5pri ntf(n%d%d\nH a,b);53t=a;a=b;b=t;printf(H%d%d\nn,a b);J J例如,用牛顿迭代法求下列方程在
1.5附近的根2x3-4x2+3x-6=0o#include math.h”main{float xx0,f,f1;x=
1.5;5do{xO=x;f=2*x0*x0*x0-4*x0*x0+3*x0-6;f1=6*x0*x0-8*x0+3;x=x0-f/f1;}whilefabsx-x0=1e-5;printf H%f\nH,x;}2二分法算法要领是先指定一种区间[x1,x2],假如函数fx在此区间是单调变化的,则可以根据fx1和fx2与否同号来确定方程fx=0在区间[x1,x2]内与否有一种实根;假如fx1和fx2同号,则fx在区间[x1,x2]内无实根,要重新变化x1和x2的值当确定fx在区间[x1,x2]内有一种实根后,可采用二分法将[x1,x2]一分为二,再判断在哪一种小区间中有实根如此不停进行下去,直到小区间足够小为止详细算法如下1输入x1和x2的值2求fx1和fx23假如fx1和fx2同号阐明在[x1,x2]内无实根,返回环节1,重新输入x1和X2的值;若fx1和fx2不一样号,则在区间[x1,x2]内必有一种实根,执行环节4o4求x1和x2的中点x0=x1+x2/2o5求fxO6判断fxO与fx1与否同号
①假如同号,则应在[xO,x2]中寻找根,止匕时x1已不起作用,用xO替代x1,用fxO替代fx1
②假如不一样号,则应在[x1,xO]中寻找根,此时x2已不起作用,用xO替代x2,用fxO替代fx27判断fxO的绝对值与否不不小于某一指定的值例如10-5若不不不小于10-5,则返回环节4反复执行环节
4、
5、6;否则执行环节88输出xO的值,它就是所求出的近似根例如,用二分法求方程2x3-4x2+3x-6=0在卜10,10之间的根#include Hmath.hHmain{float x1,x2,x0,fx1,fx2,fx0;do{printfnEnter x1x2H;scanfn%f%fn x12;X55fx1=2*x1*x1*x1-4*x1*x1+3*x1-6;fx2=2*x2*x2*x2-4*x2*x2+3*x2-6;}whilefx1*fx20;do{x0=x1+x2/2;fx0=2*x0*x0*x0-4*x0*x0+3*x0-6;iffx0*fx10{x2=x0;fx2=fx0;}else{x1=x0;fx1=fxO;}}whilefabsfx01e-5;printfn%f\nH,xO;定积分J./UM的几何意义是求曲线y=fx、x=a、x=b以及X轴所围成的面积梯形法计算定积分
3.可以近似地把面积视为若干小的梯形面积之和例如,把区间[a,b]提成n个长度相等的小区间,每个小区间的长度为h=b-a/n,第i个小梯形的面积为[fa+i-1-h+fa+i-h]-h/2,将n个小梯形面积加起来就得到定积分的近似值r bV]./xdx弋Z[/〃+/—D•/+/〃+,•力]•力/2/=I根据以上分析,给出“梯形法’求定积分的N-S构造图输入区间端点a,b输入等分数nh=b-a/2,s=0i从1到nsi=fa+i-1*h+fa+i*h*h/2s=s+si输出s上述程序的几何意义比较明显,轻易理解不过其中存在反复计算,每次循环都要计算小梯形的上、下底其实,前一种小梯形的下底就是后一种小梯形的上底,完全不必反复计算为此理如下改善:f b,h fbI2+£•[/«/2++•/]fxdx*IJ a/M1八y0a/…b矩形法求定积分则更简朴,就是将等分出来的图形当作矩形,而不是梯形♦4丫*x+3*;+2dx例如求定积分J
0..“.的值等分数n=1000#include nmath.hHfloat DJFfloat a,float b{float t,h;int nJ;float HSZfloat x;n=1000;h=fabsa-b/n;t=HSZa+HSZb/2;fori=1;i=n-1;i++t=t+HSZa+i*h;t=t*h;returnt;float HSZfloatx{returnx*x+3*x+2;}main{float y;y=DJF04;3其他常见算法k迭代法
1.其基本思想是把一种复杂的计算过程转化为简朴过程的多次反复每次反复都从旧值的基础上递推出新值,并由新值替代旧值例如,猴子吃桃问题猴子第一天摘下若干个桃子,当即吃了二分之一,还不过瘾,又多吃了一种第二天早上又将剩余的桃子吃掉二分之一,又多吃了一种后来每天早上都吃了前一天剩余的二分之一零一种到第10天早上想再吃时,就只剩一种桃子了编程求第一天共摘多少桃子main{int day,peach;peach=1;forday=9;day=1;day-peach=peach+1*2;printfnThe firstday:%d\rT,peach;}又如,用迭代法求x=G的根求平方根的迭代公式是Xn+1=
0.5xXn+a/Xn[算法]1设定一种初值Xo2用上述公式求出下一种值xi再将代入上述公式,求出下一种值3X1X2如此继续下去,直到前后两次求出的值和满足如下关系4X Xn+1Xn|Xn+1-Xn|106include nmath.hnmain{floata,x0,x1;scanfH%fH,a;x0=a/2;x1=x0+a/x0/2;do{x0=x1;x1=x0+a/x0/2;}whilefabsx0-x1=1e-5;printfH%f\nH,x1;进制转换
2.1十进制数转换为其他进制数一种十进制正整数m转换成r进制数的思绪是,将m不停除以r取余数,直到商为0时止,以反序输出余数序列即得到成果注意,转换得到的不是数值,而是数字字符串或数字串例如,任意读入一种十进制正整数,将其转换成二至十六任意进制的字符串void tranintmjnt r,char str[],int*n{char sb[]=HABCDEFH;int i=0,g;do{g=m%r;str[i]=sb[g];m=m/r;;i++}whilem!=0;*n=i;main{int xrO;frO为进制基数*/5int i,n;/*n中寄存生成序列的元素个数*/char a
1、任意读入一种二至十六进制数字符串,转换成十进制数后输出include string.hHinclude ctype.hmain{char x
[20];int r,d;getsx;/*输入一种r进制整数序列*/scanfH%d,,r;/*输入待处理的进制基数2-16//Jd=Tranx,r;printf%s=%d\n xd;55int Tranchar*p,int r{int d,i cr;char fhc;35d=0;fh=*p;iffh==,-f p++;forQ=0;ivstrlenp;i++{c=*p+i;iftoupperc=,A cr=touppercJA1+10;else cr=c-O;d=d*r+cr;iffh==-d=-d;returnd;矩阵转置
3.矩阵转置的算法要领是:将一种m行n列矩阵即mxn矩阵的每一行转置成另一种nxm矩阵的对应列例
1、将如下2x3矩阵转置后输出即将123转置成144562536main{int a
[2]
[3],b
[3]
[2],i,j k=1;sfori=0;i2;i++forj=0;j3;j++a[i][j]=k++;/*如下将a的每一行转存到b的每一列*/fori=0;i2;i++forj=0;j3;j++bD][i]=a[i]D];fori=0;i3;i++/*输出矩阵b*/{forj=0;j2;j++printf%3d,b[i][j];printf\n;}字符处理
4.1字符记录对字符串中多种字符出现的次数的记录经典例题任意读入一种只含小写字母的字符串,记录其中每个字母的个数include“stdio.h”main{char a
[100];int n
[26]={0};int i;/*定义26个计数器并置初值07getsa;fori=0;a[i]!=VT;i++/*n
[0]中寄存W的个数,n
[1]中寄存b的个数……*/“矶卜宣]++;/*各字符的ASCII码值减a的ASCII码值,恰好得对应计数器下标*/fori=0;i26;i++,ifn[i]!=0printfH%c:%d\n”i+a,n[i];2字符加密例如、对任意一种只具有英文字母的字符串,将每一种字母用其后的第三个字母替代后输出字母X后的第三个字母为A,字母丫后的第三个字母为B,字母Z后的第三个字母为Co include“stdio.h”include string.hHmain{char a
[80]=China”;int i;fori=0;istrlena;i++ifa[i]=,x,a[i]=,z,||a[i]=,X,a[i]=,Z,a[i]=a[i]-26+3;else a[i]=a[i]+3;putsa;整数各数位上数字的获取
5.算法关键是运用“任何正整数整除10的余数即得该数个位上的数字”的特点,用循环从低位到高位依次取出整数的每一数位上的数字例
1、任意读入一种5位整数,输出其符号位及从高位到低位上的数字main{long x;int wq,b s,g;55scanfH%ldH,x;ifx0{printf”-J;x=-x;}w=x/10000;/*求万位上的数字*/q=x/1000%10;/*求千位上的数字*/b=x/100%10;/*求百位上的数字*/s=x/10%10;/*求十位上的数字*/g=x%10;/*求个位上的数字*/printfH%d,%d%d%d%d\nH,w,q,b sg;55555例
2、任意读入一种整数,依次输出其符号位及从低位到高位上的数字[分析]此题读入的整数不懂得是几位数,但可以用如下示例的措施完毕此题例如读入的整数为3796,寄存在x中,执行x%10后得余数为6并输出;将x/10得379后赋值给Xo再执行x%10后得余数为9并输出;将x/10得37后赋值给x……直到商x为0时终止main{long x;scanfn%ldn,x;ifx0{printfn-H;x=-x;}do{/*为了能对的处理0,要用do_while循环*/printfH%d H,x%10;x=x/10;}whilex!=0;printfH\nn;}例
3、任意读入一种整数,依次输出其符号位及从高位到低位上的数字[分析]此题必须借助数组将依次求得的低位到高位的数字保留后,再逆序输出main{long x;int a
[20],i,j;scanfn%ldn x;5ifx0{printfn-H;x=-x;}i=0;do{a[i]=x%10;x=x/10;i++;}whilex!=0;forj=i-1;j=0;j-printfH%d H,a[j];printfH\nH;辗转相除法求两个正整数的最大公约数
6.该算法的要领是假设两个正整数为a和b,先求出前者除后来者的余数,寄存到变量r中,若r不;为0,则将b的值得赋给a,将r的值得赋给b再求出a除以b的余数,仍然寄存到变量r中……如此反复,直至r为0时终止,此时b中寄存的即为本来两数的最大公约数例
1、任意读入两个正整数,求出它们的最大公约数[法一用while循环时,最大公约数寄存于b中]main{int a,b,r;do scanfn%d%dn,a b;5whilea=0||b=0;/*保证a和b为正整数*/r=a%b;whiler!=O{a=b;b=r;r=a%b;}printfn%d\nH b;J[法二用do…while循环时,最大公约数寄存于a中]main{int a,b,r;do scanf,%d%d,,a,b;5whilea=0||b=0;/*保证a和b为正整数*/do{r=a%b;a=b;b=r;}whiler!=0;printfn%d\nH,a;}【引申】可以运用最大公约数求最小公倍数提醒:两个正整数a和b的最小公倍数=axb/最大公约数例
2、任意读入两个正整数,求出它们的最小公倍数[法一运用最大公约数求最小公倍数]main{int a b,r x,y;55do scantn%d%dn,ab;3whilea=0||b=0;/*保证a和b为正整数*/x=a;y=b;/*保留a、b本来的值*/r=a%b;%whiler!=0{a=b;b=r;r=a%b;}printf d\n”,x*y/b;[法二若其中一数的最小倍数也是另一数的倍数,该最小倍数即为所求]main{int a,b,r,i;do scanfn%d%dn ab;33whilea=0||b=0;/*保证a和b为正整数*/;i=1whilea*i%b!=O i++;printf%d\nn i*a;5求最值
7.即求若干数据中的最大值或最小值算法要领是首先将若干数据寄存于数组中,一般假设第一种元素即为最大值或最小值,赋值给最终寄存最大值或最小值的max或min变量中,然后将该量max或min的值与数组其他每一种元素进行比较,一旦比该量还大或小,则将此元素的值赋给max或min……所有数如此比较完毕,即可求得最大值或最小值例
1、任意读入10个数,输出其中的最大值与最小值#define N10main{int a[N]J,max min;3;fori=0;iN;i++scanfH%dH,a[i]max=min=a
[0];fori=1;iN;i++ifa[i]max max=a[i];else ifa[i]min min=a[i];printfnmax=%d min=%d\nn,max min;3J判断素数
8.素数又称质数,即“只能被1和自身整除的不小于1的自然数”判断素数的算法要领就是根据数学定义,即若该不小于1的正整数不能被2至自身减1整除,就是素数例
1、任意读入一种正整数,判断其与否为素数main{int x,k;do scanfn%dn x;5whilex=1;/*保证读入不小于1的正整数*/fork=2;k=x-1;k++if x%k==O break;/*一旦能被2~自身-1整除,就不也许是素数*/ifk==x printf%d issushu\nH,x;else printfH%d isnot sushu\nH,x;}以上例题可以用如下两种变形来处理需要使用辅助判断的逻辑变量[变形一】将2~自身-1”的范围缩小至“2~自身的二分之一”main{int x,k,flag;do scanfH%dn,x;whilex=1;flag=1;/*先假设x就是素数*/fork=2;k=x/2;k++if x%k==O{flag=0;break;}/*一旦不也许是素数,即置flag为0*/ifflag==1printfn%d issushu\nn x;5【解析】程序中加粗部分为算法的关键,如同互换两个杯子里的饮料,必须借助第三个空杯子;假设输入的值分别为
3、7,则第一行输出为3,7第二行输出为7,30其中t为中间变量,起到“空杯子”的作用注意三句赋值语句赋值号左右的各量之间的关系!【应用】例
2、任意读入三个整数,然后按从小到大的次序输出main{int a,b,c,t;scanf%d%d%d,a,b,c;/*如下两个if语句使得a中寄存的数最小*/ifab{t=a;a=b;b=t;}ifac{t=a;a=c;c=t;}/*如下if语句使得b中寄存的多次小*/ifbc{t=b;b=c;c=t;}printf%d,%d,%d\n,a,b,c;}累加
2.累加算法的要领是形如s二s+A”的累加式,此式必须出目前循环中才能被反复执行,从而实现累加功能“A”一般是有规律变化的体现式,s在进入循环前必须获得合适的初值,一般为Oo例
1、求1+2+3+……+100的和main{int i,s;s=0;i=1;whilei=100{s=s+i;/*累加式*/i=i+1;/*特殊的累加式*/printfH1+2+3+...+100=%d\nH,s;}【解析】程序中加粗部分为累加式的经典形式,赋值号左右都出现的变量称为累加器,其中“i=i+1”为特殊的累加式,每次累加的值为1,这样的累加器又称为计数器累乘
3.else printf%d isnot sushu\nH,x;}【变形二】将“2〜自身-1”的范围缩小至“2〜自身的平方根”include nmath.hnmain{int x,k,flag;do scanfn%dH,x;whilex=1;flag=1;/*先假设x就是素数*/fork=2;k=intsqrtx;k++if x%k==0{flag=0;break;}/*一旦不也许是素数,即置flag为0*/ifflag==1printfH%d issushu\nH,x;else printf%d isnot sushu\nH,x;例
2、用筛选法求得100以内的所有素数;算法为1定义一维数组a,其初值为2,3,……,100;2若矶k]不为0,则将该元素后来的所有a[k]的倍数的数组元素置为033a中不为0的元素,均为素数#include math.h#include stdio.hmain{int k,j,a
[101];clrscr;/*清屏函数*/fork=2;k101;k++a[k]=k;fork=2;ksqrt101;k++forj=k+1;j101;j++ifa[k]!=Oa[j]!=OifaU]%a[k]==Oa[j]=O;fork=2;k101;k++ifa[k]!=0printfH%5dH a[k];5数组元素的插入、删除
9.1数组元素的插入此算法一般是在已经有序的数组中再插入一种数据,使数组中的数列仍然有序算法要领是假设待插数据为x,数组a中数据为升序序列
①先将x与a数组目前最终一种元素进行比较,若比最终一种元素还大,就将x放入其后一种元素中;否则进行如下环节;
②先查找到待插位置从数组a的第1个元素开始找到不比x小的第一种元素,设其下标为i;
③将数组a中原最终一种元素至第i个元素依次一一后移一位,让出待插数据的位置,即下标为i的位置;
④将x寄存到ai中例题参见前面‘排序’中插入法排序的例1”2数组元素的删除此算法的要领是首先要找到也也许找不到待删除元素在数组中的位置即下标,然后将待删元素后的每一种元素向前移动一位,最终将数组元素的个数减1例
1、数组a中有若干不一样考试分数,任意读入一种分数,若与数组a中某一元素值相等,就将该元素删除#define N6main{int fs[N]={69,90,85,56,44,80},x;int i,j,n;n=N;scanf%d,x;/*任意读入一种分数值*//*如下查找待删分数的位置,即元素下标*/fori=0;in;i++if fs[i]==x break;ifi==n printfNotfound!\n;else/*将待删位置之后的所有元素----------前移*/{forj=i+1;jn;j++fs[j-1]=fs[j];n=n-1;/*元素个数减1*/fori=0;in;i++printf%d,fs[i];二维数组的其他经典问题
10.1方阵的特点行列相等的矩阵又称方阵其两条对角线中“\”方向的为主对角线,“/”方向的为副对角线主对角线上各元素的下标特点为行列值相等;副对角线上各元素的下标特点为行列值之和都为阶数加1o主对角线及其如下部分行值不小于列值称为下三角例
1、输出如下5阶方阵1222231222331223331233331#define N5main{int a[N][N],i,j;fori=0;iN;i++forj=0;jN;j++if i==j a[i]D]=1;else ifija[i][j]=2;else a[i][j]=3;fori=0;iN;i++{forj=0;jN;j++printfH%3dH a[i][j];5printfH\nH;}例
2、输出如下5阶方阵1234523456345674567856789#define N5main{intfori=0;iN;i++forj=0;jN;j++a[i]U]=i+j+1;/*沿副对角线平行线方向考察每个元素,其值等于行列值之和+1*/fori=0;iN;i++{forj=0;jN;j++;printfH%3dH a[i][j]5printfH\nH;}2杨辉三角形;杨辉三角形的每一行是x+yn的展开式各项的系数例如第一行是x+yO,其系数为1第二行是;;x+y1,其系数为1,1第三行是x+y2,其展开式为x2+2xy+y2,系数分别为1,2,1……直观形式如下11112113311464115101051分析以上形式,可以发现其规律是n阶方阵的下三角,第一列和主对角线均为1,其他各元素是它的上一行、同一列元素与上一行、前一列元素之和例
1、编程输出杨辉三角形的前10行#define N10main{intfori=0;iN;i++a[i]
[0]=a[i][i]=1;for占2;ivN;i++forj=1;j=i-1;j++a[i]ffl=a[i-1]U-1]a[i-1]U];+fori=0;iN;i++{forj=0;j=i;j++printfM%4dH a[i][j];5;printfn\nH例
2、以等腰三角形的形状输出杨辉三角形的前5行111121133114641#define N5main{int a[N][N],i,j;fori=0;iN;i++a[i]
[0]=a[i][i]=1;fori=0;iN;i++forj=1;ji;j++a[i]U]=a[i-1]U-1]a[i-1]U];+fori=0;iN;i++{forj=N-i;j=0;j-printf;/*输出时每行前导空格递减*/forj=0;j=i;j++printfH%4dH,a[i][j];printfn\nn;累乘算法的要领是形如s=s*A”的累乘式,此式必须出目前循环中才能被反复执行,从而实现累乘功能“A”一般是有规律变化的体现式,s在进入循环前必须获得合适的初值,一般为10例
1、求10![分析]10!=1x2x3x……xiomain{int i;long c;C=1;i=1;whilei=10{c=c*i;/*累乘式*/i=i+1;printfH1*2*3*...*10=%ld\nH c;5
二、非数值计算常用经典算法穷举
1.也称为“枚举法”,即将也许出现的每一种状况一一测试,判断与否满足条件,一般采用循环来实现例
1、用穷举法输出所有的水仙花数即这样的三位正整数其每位数位上的数字的立方和与该数相等,例如:1*1*1+5*5*5+3*3*3=153[法一]main{intx,g,s,b;forx=100;x=999;x++{g=x%10;s=x/10%10;b=x/100;ifb*b*b+s*s*s+g*g*g==xprintf%d\n,x;【解析】此措施是将100到999所有的三位正整数一一考察,即将每一种三位正整数的个位数、十位数、百位数一一求出各数位上的数字的提取算法见下面的“数字处理”,算出三者的立方和,一旦与原数相等就输出共考虑了900个三位正整数[法二]main{intg,s,b;forb=1;b=9;b++fors=0;s=9;s++forg=0;g=9;g++ifb*b*b+s*s*s+g*g*g==b*100+s*10+g printfn%d\nn b*100+s*10+g;5【解析】此措施是用1到9做百位数字、0到9做十位和个位数字,将构成的三位正整数与每一组的三个数的立方和进行比较,一旦相等就输出共考虑了900个组合外循环单独执行的次数为9,两个内循环单独执行的次数分别为10次,故if语句被执行的次数为9x10x10=900,即900个三位正整数与法一判断的次数同样排序
2.1冒泡排序起泡排序假设要对具有n个数的序列进行升序排列,冒泡排序算法环节是
①从寄存序列的数组中的第一种元素开始到最终一种元素,依次对相邻两数进行比较,若前者大后者小,则互换两数的位置;
②第
①趟结束后,最大数就寄存到数组的最终一种元素里了,然后从第一种元素开始到倒数第二个元素,依次对相邻两数进行比较,若前者大后者小,则互换两数的位置;
③反复环节
①n-1趟,每趟比前一趟少比较一次,即可完毕所求例
1、任意读入10个整数,将其用冒泡法按升序排列后输出#define n10main{int a[n],i,j,t;fori=0;in;i++scanf%d,a[i];forj=1;j=n-1;j++/*n个数处理n-1趟*/fori=0;i=n-1-j;i++/*每趟比前一趟少比较一次*/ifa[i]a[i+1]{t=a[i];a[i]=a[i+1];a[i1]=t;}+fori=0;in;i++printf%d\n,a[i];}2选择法排序选择法排序是相对好理解的排序算法假设要对具有n个数的序列进行升序排列,算法环节是
①从数组寄存的n个数中找出最小数的下标算法见下面的“求最值”,然后将最小数与第1个数互换位置;
②除第1个数以外,再从其他n-1个数中找出最小数即n个数中的次小数的下标,将此数与第2个数互换位置;
③反复环节
①n-1趟,即可完毕所求例
1、任意读入10个整数,将其用选择法按升序排列后输出#define n10main{int a[n],i,j,k,t;fori=0;in;i++scanfH%dM,a[i];fori=0;in-1;i++/*处理n-1趟*/{k=i;/*总是假设此趟处理的第一种即所有数的第i个数最小,k记录其下标*/forj=i+1;jn;j++ifaU]a[k]k=j;if k!=i{t=a[i];a[i]=a[k];a[k]=t;}fori=0;in;i++printfH%d\nn,a[i];3插入法排序要想很好地掌握此算法,先请理解“有序序列的插入算法”,就是将某数据插入到一种有序序列后,该序列仍然有序插入算法参见下面的“数组元素的插入,例
1、将任意读入的整数X插入一升序数列后,数列仍按升序排列#define n10main{int a[n]={-1,3,6,9,13,22,27,32,49},x,j,k;/*注意留一种空间给待插数*/%scanf”d”,x;ifxa[n-2]a[n-1]=x;/*比最终一种数还大就往最终一种元素中寄存*/else/*查找待插位置*/{j=0;while j=n-2xa[j]j++;fork=n-2;k=j;k--/*从最终一种数开始直到待插位置上的数依次后移一位//a[k+1]=a[k];a[j]=x;/*插入待插数*/forj=0;j=n-1;j++printfH%d H,a[j];插入法排序的要领就是每读入一种数立即插入到最终寄存的数组中,每次插入都使得该数组有序例
2、任意读入10个整数,将其用插入法按降序排列后输出提醒将第2至第10个数一一有序插入到数组a中#define n10main{int a[n],ij kx;55;scanfM%dn a
[0]/*读入第一种数,直接存到a
[0]中*/5forj=1;jn;j++/*将第2至第10个数一一有序插入到数组a中*/{scanf%d,x;ifxaU-1]aU]=x;/*比原数列最终一种数还小就往最终一种元素之后寄存新读的数*/else/*如下查找待插位置*/{i=0;whilexa[i]i=j-1i++;/*如下for循环从原最终一种数开始直到待插位置上的数依次后移一位*/fork=j-1;k=i;k-a[k+1]=a[k];a[i]=x;/*插入待插数*/fori=0;in;i++printf%d\n,a[i];4归并排序即将两个都升序或降序排列的数据序列合并成一种仍按原序排列的序列例
1、有一种具有6个数据的升序序列和一种具有4个数据的升序序列,将两者合并成一种具有10个数据的升序序列#define m6#define n4main{int a[m]={-3,6,19,26,68,100},b[n]={8,10,12,22;int i,j,k,c[m+n];i=j=k=O;whileimjn/*将a、b数组中的较小数依次寄存到c数组中*/{ifa[i]b[j]{c[k]=a[i]i++;};else{c[k]=b[j];j++;}k++;whilei=mjn/*若a中数据所有寄存完毕,将b中余下的数所有寄存到c中*/{c[k]=b[j];k++;j++;}whilej=nim/*若b中数据所有寄存完毕,将a中余下的数所有寄存到c中*/{c[k]=a[i];k++;i++;}fori=0;im+n;i++printfn%d nc[i];5查找
3.1次序查找即线性查找次序查找的思绪是将待查找的量与数组中的每一种元素进行比较,若有一种元素与之相等则找到;若没有一种元素与之相等则找不到例
1、任意读入10个数寄存到数组a中,然后读入待查找数值,寄存到X中,判断a中有无与x等值的数#define N10main{int a[N],i,x;fori=0;iN;i++scanf%dn a[i];3/*如下读入待查找数值*/scanfn%dn x;5fori=0;iN;i++ifa[i]==x break;/*一旦找到就跳出循环*/ifiN printfTound!\nH;else printfHNotfound!\nH;}2折半查找即二分法次序查找的效率较低,当数据诸多时,用二分法查找可以提高效率使用二分法查找的前提是数列必须有序二分法查找的思绪是要查找的关键值同数组的中间一种元素比较,若相似则查找成功,结束;否则鉴别关键值落在数组的哪半部分,就在这半部分中按上述措施继续比较,直到找到或数组中没有这样的元素值为止例
1、任意读入一种整数x,在升序数组a中查找与否有与x等值的元素#define n10main{int a[n]={2,4,7,9,12,25,36,50,77,90;int x,high,low mid;/*x为关键值*/5scanfn%dn x;3high=n-1;low=0;mid=high+low/2;whilea[mid]!=xlowhigh{ifxa[mid]high=mid-1;/*修改区间上界*/else low=mid+1;/*修改区间下界*/mid=high+low/2;ifx==a[mid]printfHFound%d,%d\n\x,mid;else printfnNotfound\nn;
三、数值计算常用经典算法级数计算
1.级数计算的关键是“描述出通项”,而通项的描述法有两种一为直接法、二为间接法又称递推法直接法的要领是运用项次直接写出通项式;递推法的要领是运用前一种或多种通项写出后一种通项可以用直接法描述通项的级数计算例子有11+2+3+4+5+……21+1/2+1/3+1/4+1/5+......等等可以用间接法描述通项的级数计算例子有31+1/2+2/3+3/5+5/8+8/13+……41+1/2!+1/3!+1/4!+1/5!+……等等1直接法求通项例
1、求1+1/2+1/3+1/4+1/5+……+1/100的和main{float s;int i;s=
0.0;fori=1;i=100;i++s=s+
1.0/i;printf1+1/2+1/3+...+1/100=%f\n,s;【解析】程序中加粗部分就是运用项次i的倒数直接描述出每一项,并进行累加注意:由于i是整数,故分子必须写成
1.0的形式!2间接法求通项即递推法例
2、计算下列式子前20项的和1+1/2+2/3+3/5+5/8+8/13+……[分析]此题后项的分子是前项的分母,后项的分母是前项分子分母之和main{float s,fz,fm,t,fz1;int i;s=1;/*先将第一项的值赋给累加器s7fz=1;fm=2;t=fz/fm;/*将待加的第二项存入t中*/fori=2;i=20;i++{s=s+t;/*如下求下一项的分子分母*/fz1=fz;/*将前项分子值保留到fz1中*/fz=fm;/*后项分子等于前项分母*/fm=fz1+fm;/*后项分母等于前项分子、分母之和*/t=fz/fm;printfn1+1/2+2/3+...=%f\nH s;J下面举一种通项的一部分用直接法描述,另一部分用递推法描述的级数计算的例子:例
3、计算级川12l数的值,当通项的绝对值不不小于eps时计算停止yinclude math.hfloat gfloatx,float eps;main{floatx,eps;scanfn%f%fn x,eps;5printfn\n%f%f\n,x gx,eps;35float gfloatx,float eps{int n=1;float st;5S=1;t=1;do{t=t*x/2*n;s=s+n*n+1*t;/*加波浪线的部分为直接法描述部分,t为递推法描述部分*/n++;}whilefabsteps;return s;一元非线性方程求根
2.1牛顿迭代法牛顿迭代法又称牛顿切线法先任意设定一种与真实的根靠近的值xO作为第一次近似根,由xO求出fxO,过xO,fxO点做fx的切线,交x轴于x1,把它作为第二次近似根,再由x1求出fx1,过x1,fx1点做fx的切线,交x轴于x2,……如此继续下去,直到足够靠近例如|x-x0|1e-6时真正的根x*为止而f xO=fxO/x1-xO因此x1=xO-fxO/f xO。
个人认证
优秀文档
获得点赞 0