ImageVerifierCode 换一换
格式:DOCX , 页数:58 ,大小:38.64KB ,
资源ID:7690609      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7690609.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(C语言经典算法大全.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

C语言经典算法大全.docx

1、C语言经典算法大全C语言经典算法大全 老掉牙 数、运算 关于赌博 集合问题 排序 搜寻 矩阵1.河内之塔说明河内之塔(TowersofHanoi)是法国人(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家EdouardLucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也

2、就是世界末日来临之时。解法如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是:A-B、A-C、B-C这三个步骤,而被遮住的部份,其实就是进入程式的递回处理。事实上,若有n个盘子,则移动完毕所需之次数为2n-1,所以当盘数为64时,则所需次数为:264-1=#includevoidhanoi(intn,charA,charB,charC)if(n=1)printf(Movesheet%dfrom%cto%cn,n,A,C);elsehanoi(n-1,A,C,B);

3、printf(Movesheet%dfrom%cto%cn,n,A,C);hanoi(n-1,B,A,C);intmain()intn;printf(请输入盘数:);scanf(%d,&n);hanoi(n,A,B,C);return0;说明Fibonacci为1200年代的欧洲数学家,在他的着作中曾经提到:若有一只免子每个月生一只小免子,一个月后小免子也开始生产。起初只有一只免子,一个月后就有两只免子,二个月后有三只免子,三个月后有五只免子(小免子投入生产).。如果不太理解这个例子的话,举个图就知道了,注意新生的小免子需一个月成长期才会投入生产,类似的道理也可以用于植物的生长,这就是Fibo

4、nacci数列,一般习惯称之为费氏数列,例如以下:1、1、2、3、5、8、13、21、34、55、89.解法依说明,我们可以将费氏数列定义为以下:fn=fn-1+fn-2ifn1fn=nifn=0,1#include#include#defineN20intmain(void)intFibN=0;inti;Fib0=0;Fib1=1;for(i=2;iN;i+)Fibi=Fibi-1+Fibi-2;for(i=0;iN;i+)printf(%d,Fibi);printf(n);return0;#include#defineN12longcombi(intn,intr)inti;longp=1;

5、for(i=1;i=r;i+)p=p*(n-i+1)/i;returnp;voidmain()intn,r,t;for(n=0;n=N;n+)for(r=0;r=n;r+)inti;/*排版设定开始*/if(r=0)for(i=0;i=(N-n);i+)printf();elseprintf();/*排版设定结束*/printf(%3d,combi(n,r);printf(n);说明三色旗的问题最早由所提出,他所使用的用语为DutchNationFlag(Dijkstra为荷兰人),而多数的作者则使用Three-ColorFlag来称之。假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子

6、上的旗子颜色并没有顺序,您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳子上进行这个动作,而且一次只能调换两个旗子。解法在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来作辅助,问题的解法很简单,您可以自己想像一下在移动旗子,从绳子开头进行,遇到蓝色往前移,遇到白色留在中间,遇到红色往后移,如下所示:只是要让移动次数最少的话,就要有些技巧:如果图中W所在的位置为白色,则W+1,表示未处理的部份移至至白色群组。如果W部份为蓝色,则B与W的元素对调,而B与W必须各+1,表示两个群组都多了一个元素。如果W所在的位置是红色,则将W与R交换,但R要减

7、1,表示未处理的部份减1。注意B、W、R并不是三色旗的个数,它们只是一个移动的指标;什幺时候移动结束呢?一开始时未处理的R指标会是等于旗子的总数,当R的索引数减至少于W的索引数时,表示接下来的旗子就都是红色了,此时就可以结束移动,如下所示:#include#include#include#defineBLUEb#defineWHITEw#defineREDr#defineSWAP(x,y)chartemp;temp=colorx;colorx=colory;colory=temp;intmain()charcolor=r,w,b,w,w,b,r,b,w,r,0;intwFlag=0;intbF

8、lag=0;intrFlag=strlen(color)-1;inti;for(i=0;istrlen(color);i+)printf(%c,colori);printf(n);while(wFlag=rFlag)if(colorwFlag=WHITE)wFlag+;elseif(colorwFlag=BLUE)SWAP(bFlag,wFlag);bFlag+;wFlag+;elsewhile(wFlagrFlag&colorrFlag=RED)rFlag-;SWAP(rFlag,wFlag);rFlag-;for(i=0;istrlen(color);i+)printf(%c,colori

9、);printf(n);return0;说明老鼠走迷宫是递回求解的基本题型,我们在二维阵列中使用2表示迷宫墙壁,使用1来表示老鼠的行走路径,试以程式求出由入口至出口的路径。解法老鼠的走法有上、左、下、右四个方向,在每前进一格之后就选一个方向前进,无法前进时退回选择下一个可前进方向,如此在阵列中依序测试四个方向,直到走到出口为止,这是递回的基本题,请直接看程式应就可以理解。#include#includeintvisit(int,int);intmaze77=2,2,2,2,2,2,2,2,0,0,0,0,0,2,2,0,2,0,2,0,2,2,0,0,2,0,2,2,2,2,0,2,0,2,2

10、,2,0,0,0,0,0,2,2,2,2,2,2,2,2;intstartI=1,startJ=1;printf(n);voidbacktrack(inti)intj;if(iN)showAnswer();elsefor(j=1;j=N;j+)if(columnj=1&rupi+j=1&lupi-j+N=1)queeni=j;hanoihanoihanoihanoihanoihanoihanoihanoihanoihanoihanoihanoihanoihanoihanoiize;svalues)ize)printf(%st%dn,aitemi.name,aitemi.price);print

11、f(合计t%dn,valueLIMIT);return0;JavaclassFruitprivateStringname;privateintsize;privateintprice;publicFruit(Stringname,intsize,intprice)=name;=size;=price;publicStringgetName()returnname;publicintgetPrice()returnprice;publicintgetSize()returnsize;publicclassKnapsackpublicstaticvoidmain(Stringargs)finali

12、ntMAX=8;finalintMIN=1;intitem=newintMAX+1;intvalue=newintMAX+1;Fruitfruits=newFruit(李子,4,4500),newFruit(苹果,5,5700),newFruit(橘子,2,2250),newFruit(草莓,1,1100),newFruit(甜瓜,6,6700);for(inti=0;i;i+)for(ints=fruitsi.getSize();svalues)etSize()t+fruitsitemi.getPrice();合计t+valueMAX);说明蒙地卡罗为摩洛哥王国之首都,该国位于法国与义大利国

13、境,以赌博闻名。蒙地卡罗的基本原理为以乱数配合面积公式来进行解题,这种以机率来解题的方式带有赌博的意味,虽然在精确度上有所疑虑,但其解题的思考方向却是个值得学习的方式。解法蒙地卡罗的解法适用于与面积有关的题目,例如求PI值或椭圆面积,这边介绍如何求PI值;假设有一个圆半径为1,所以四分之一圆面积就为PI,而包括此四分之一圆的正方形面积就为1,如下图所示:如果随意的在正方形中投射飞标(点)好了,则这些飞标(点)有些会落于四分之一圆内,假设所投射的飞标(点)有n点,在圆内的飞标(点)有c点,则依比例来算,就会得到上图中最后的公式。至于如何判断所产生的点落于圆内,很简单,令乱数产生X与Y两个数值,如

14、果X2+Y2等于1就是落在圆内。#include#include#include#defineN50000intmain(void)inti,sum=0;doublex,y;srand(time(NULL);for(i=1;iN;i+)x=(double)rand()/RAND_MAX;y=(double)rand()/RAND_MAX;if(x*x+y*y)1)sum+;printf(PI=%fn,(double)4*sum/N);return0;说明除了自身之外,无法被其它整数整除的数称之为质数,要求质数很简单,但如何快速的求出质数则一直是程式设计人员与数学家努力的课题,在这边介绍一个着名

15、的Eratosthenes求质数方法。解法首先知道这个问题可以使用回圈来求解,将一个指定的数除以所有小于它的数,若可以整除就不是质数,然而如何减少回圈的检查次数?如何求出小于N的所有质数?首先假设要检查的数是N好了,则事实上只要检查至N的开根号就可以了,道理很简单,假设A*B=N,如果A大于N的开根号,则事实上在小于A之前的检查就可以先检查到B这个数可以整除N。不过在程式中使用开根号会精确度的问题,所以可以使用i*i=N进行检查,且执行更快。再来假设有一个筛子存放1N,例如:23456789101112131415161718192021.N先将2的倍数筛去:23579111315171921

16、.N再将3的倍数筛去:235711131719.N再来将5的倍数筛去,再来将7的质数筛去,再来将11的倍数筛去.,如此进行到最后留下的数就都是质数,这就是Eratosthenes筛选方法(EratosthenesSieveMethod)。检查的次数还可以再减少,事实上,只要检查6n+1与6n+5就可以了,也就是直接跳过2与3的倍数,使得程式中的if的检查动作可以减少。实作C#include#include#defineN1000intmain(void)inti,j;intprimeN+1;for(i=2;i=N;i+)primei=1;for(i=2;i*i=N;i+).-4/239-4/(

17、3*2393)+4/(5*2395)-4/(7*2397)+.可以将这个公式整理为:PI=16/5-4/239-16/(53)-4/(2393)/3+16/(55)-4/(2395)/5+.也就是说第n项,若为奇数则为正数,为偶数则为负数,而项数表示方式为:16/52*n-1-4/2392*n-1/(2*n-1)如果我们要计算圆周率至10的负L次方,由于16/52*n-1-4/2392*n-1中16/52*n-1比4/2392*n-1来的大,具有决定性,所以表示至少必须计算至第n项:16/52*n-1/(2*n-1)=10-L将上面的等式取log并经过化简,我们可以求得:n=L/(2log5)

18、=L/所以若要求精确度至小数后L位数,则只要求至公式的第n项,其中n等于:n=L/+1在上式中为高斯符号,也就是取至整数(不大于L/的整数);为了计简方便,可以在程式中使用下面这个公式来计简第n项:Wn-1/52-Vn-1/(2392)/(2*n-1)这个公式的演算法配合大数运算函式的演算法为:div(w,25,w);div(v,239,v);div(v,239,v);sub(w,v,q);div(q,2*k-1,q)至于大数运算的演算法,请参考之前的文章,必须注意的是在输出时,由于是输出阵列中的整数值,如果阵列中整数位数不满四位,则必须补上0,在C语言中只要使用格式指定字%04d,使得不足位

19、数部份自动补上0再输出,至于Java的部份,使用NumberFormat来作格式化。#include#defineL1000#defineNL/4+1,s0);for(k=1;k=0;i-)ci=ai+bi+carry;if(ci10000)carry=0;else.,这只要使用除法与余数运算就可以了,例如输入input为abc,则:a=input/100b=(input%100)/10c=input%10#include#include#includeintmain(void)inta,b,c;intinput;printf(寻找Armstrong数:n);for(input=100;inp

20、ut=999;input+)a=input/100;b=(input%100)/10;c=input%10;if(a*a*a+b*b*b+c*c*c=input)printf(%d,input);printf(n);return0;说明现将举行一个餐会,让访客事先填写到达时间与离开时间,为了掌握座位的数目,必须先估计不同时间的最大访客数。解法这个题目看似有些复杂,其实相当简单,单就计算访客数这个目的,同时考虑同一访客的来访时间与离开时间,反而会使程式变得复杂;只要将来访时间与离开时间分开处理就可以了,假设访客i的来访时间为xi,而离开时间为yi。在资料输入完毕之后,将xi与yi分别进行排序(由

21、小到大),道理很简单,只要先计算某时之前总共来访了多少访客,然后再减去某时之前的离开访客,就可以轻易的解出这个问题。#include#include#defineMAX100#defineSWAP(x,y)intt;t=x;x=y;y=t;intpartition(int,int,int);voidquicksort(int,int,int);1953年三月十七日.780.708080.708080.708080.插入排序像是玩朴克一样,我们将牌分作两堆,每次从后面一堆的牌抽出最前端的牌,然后插入前面一堆牌的适当位置,例如:排序前:677792854367将77插入92前6777924367将

22、67插入77前8677792367将8插入67前67将6插入8前92将84插入92前8492854367将55插入67前8485924367.67.92.气泡排序法顾名思义,就是排序时,最大的元素会如同气泡一样移至右端,其利用比较相邻元素的方法,将大的元素交换至右端,所以大的元素会不断的往右移动,直到适当的位置为止。基本的气泡排序法可以利用旗标的方式稍微减少一些比较的时间,当寻访完阵列后都没有发生任何的交换动作,表示排序已经完成,而无需再进行之后的回圈比较与交换动作,例如:排序前:509595浮出691850909590浮出185080909580浮出50.95.6918279095.6918

23、809095由于接下来不会再发生交换动作,排序提早结束在上面的例子当中,还加入了一个观念,就是当进行至i与i+1时没有交换的动作,表示接下来的i+2至n已经排序完毕,这也增进了气泡排序的效率。#include#include#include#defineMAX10#defineSWAP(x,y)intt;t=x;x=y;y=t;voidselsort(int);3)n);return0;voidselsort(intnumber)inti,j,k,m;for(i=0;iMAX-1;i+)m=i;for(j=i+1;jMAX;j+)if(numberjnumberm)m=j;if(i!=m)SW

24、AP(numberi,numberm)printf(第%d次排序:,i+1);for(k=0;kMAX;k+)printf(%d,numberk);printf(n);voidinsort(intnumber)inti,j,k,tmp;for(j=1;jMAX;j+)tmp=numberj;i=j-1;while(tmpnumberi)numberi+1=numberi;i-;if(i=-1)break;numberi+1=tmp;printf(第%d次排序:,j);for(k=0;kMAX;k+)printf(%d,numberk);printf(n);voidbubsort(intnumb

25、er)inti,j,k,flag=1;for(i=0;iMAX-1&flag=1;i+)flag=0;for(j=0;jMAX-i-1;j+)if(numberj+1numberj)SWAP(numberj+1,numberj);flag=1;printf(第%d次排序:,i+1);for(k=0;kMAX;k+)printf(%d,numberk);printf(n);说明插入排序法由未排序的后半部前端取出一个值,插入已排序前半部的适当位置,概念简单但速度不快。排序要加快的基本原则之一,是让后一次的排序进行时,尽量利用前一次排序后的结果,以加快排序的速度,Shell排序法即是基于此一概念来改良插入排序法。解法Shell排序法最初是于1959所提出,假设要

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1