c语言经典编程282例算法

C语言基本算法_百度知道
C语言基本算法
为什么教科书上没注明要定然a为整型变量呢,用的是谭浩强的《C程序设计》,我自己算出来应该是0.5,在算法学习中,设原来a=12,答案是否与这句话有关;a&#47,有这样一个习题:写出下面赋值表达式运算后a值,题解上有一句是说a定义为整型变量?谢谢解答;=a+a,而看题解的答案是0我是一个C语言新手
提问者采纳
运算中数都是整型的.5.0中24.0这样结果就又为0了.计算结果的精度取运算的两个数中精度最高的那个;24;24它的结果会显示为0;24,精度高于整形.0为浮点型,计算结果就自动取为浮点型了。这时你如果想让结果再取为整型就在它的前面加一个强制类型转换符 (int)a&#47。例如上面的那个a&#47,结果就取整型的,如果你计算a&#47.0那么它的结果会显示为0。例如 你定义 int a=12计算a/24计算机中
提问者评价
谢谢!刚开始学习中,多谢指教!
其他类似问题
为您推荐:
c语言的相关知识
其他5条回答
题中应该有写int a吧整形变量时不会有小数的比如说 1.9 取整,是 1
a=12;a/=a+a;根据你的描述,你的程序至少应该有上述3条语句。由于a
根据计算 是0.5 ,取整则为 0 。
前面有定义a为 int 类型的
为整形变量,所以算出来的结果并不是想数学四舍五入,而是截掉小数点后面的数取整,你算的0.5没错,截掉小数点后面的就是0了还有就是有的时候声明变量时可以省略声明类型,大多编译器都按整形处理
整型变量是指像 -1 、-2 、0 、1、 2、100 这样的变量 声明为整型变量的变量不能被赋值为0.5,强制赋值的话a存储的是0
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁当前位置 &
C语言中的算法
C语言中的算法
&什么是程序?程序= 数据结构+ 算法。
对于面向对象程序设计,强调的是数据结构,而对于面向过程的程序设计语言如C、Pascal、FORTRAN等语言,主要关注的是算法。掌握算法,也是为面向对象程序设计打下一个扎实的基础。那么,什么是算法呢?
由此可见,程序设计的关键之一,是解题的方法与步骤,是算法。学习高级语言的重点,就是掌握分析问题、解决问题的方法,就是锻炼分析、分解,最终归纳整理出算法的能力。与之相对应,具体语言,如C语言的语法是工具,是算法的一个具体实现。所以在高级语言的学习中,一方面应熟练掌握该语言的语法,因为它是算法实现的基础,另一方面必须认识到算法的重要性,加强思维训练,以写出高质量的程序。
下面通过例子来介绍如何设计一个算法:
[例1-4] 输入三个数,然后输出其中最大的数。
首先,得先有个地方装这三个数,我们定义三个变量A、B、C,将三个数依次输入到A、B、C中,另外,再准备一个M A X装最大数。由于计算机一次只能比较两个数,我们首先把A与B比,大的数放入M A X中,再把M A X 与C比,又把大的数放入M A X中。最后,把M A X输出,此时M A X中装的就是A、B、C三数中最大的一个数。算法可以表
1) 输入A、B、C。
2) A与B中大的一个放入M A X中。
3) 把C与M A X中大的一个放入M A X中。
4) 输出M A X,M A X即为最大数。
其中的2 )、3 )两步仍不明确,无法直接转化为程序语句,可以继续细化:
2) 把A与B中大的一个放入M A X中,若A & B,则MAX &A;否则MAX &B。
3) 把C与M A X中大的一个放入M A X中,若C & M A X,则M A X&C。
于是算法最后可以写成:
1) 输入A,B,C。
2) 若A & B,则MAX &A;
否则M A X&B。
3) 若C & M A X,则M A X&C。
4) 输出M A X,M A X即为最大数。
这样的算法已经可以很方便地转化为相应的程序语句了。
[例1-5] 猴子吃桃问题:有一堆桃子不知数目,猴子第一天吃掉一半,觉得不过瘾,又多吃了一只,第二天照此办理,吃掉剩下桃子的一半另加一个,天天如此,到第十天早上,猴子发现只剩一只桃子了,问这堆桃子原来有多少个?
此题粗看起来有些无从着手的感觉,那么怎样开始呢?假设第一天开始时有a1只桃子,第二天有a2只,. . .,第9天有a9只,第1 0天是a1 0只,在a1, a2, . . .,a1 0中,只有a1 0= 1是知道的,现要求a1,而我们可以看出,a1, a2, . .,a1 0之间存在一个简单的关系:
a9= 2 * ( a1 0+ 1 )
a8= 2 * ( a9+ 1 )
a1= 2 * ( a2+ 1 )
也就是:ai= 2 * ( ai + 1+1) i=9,8,7,6,...,1
这就是此题的数学模型。
再考察上面从a9,a8直至a1的计算过程,这其实是一个递推过程,这种递推的方法在计算机解题中经常用到。另一方面,这九步运算从形式上完全一样,不同的只是ai的下标而已。由此,我们引入循环的处理方法,并统一用a0表示前一天的桃子数,a1表示后一天的桃子数,将算法改写如下:
1) a1=1; {第1 0天的桃子数,a1的初值}
i = 9。{计数器初值为9}
2) a0= 2 * ( a1+ 1 )。{计算当天的桃子数}
3) a1= a0。{将当天的桃子数作为下一次计算的初值}
4) i=i-1。
5) 若i & = 1,转2 )。
6) 输出a0的值。
其中2 )~5 )步为循环。
这就是一个从具体到抽象的过程,具体方法是:
1) 弄清如果由人来做,应该采取哪些步骤。
2) 对这些步骤进行归纳整理,抽象出数学模型。
3) 对其中的重复步骤,通过使用相同变量等方式求得形式的统一,然后简练地用循环解决。
算法的描述方法有自然语言描述、伪代码、流程图、N - S图、PA D 图等。
1.4.1 流程图与算法的结构化描述
流程图是一种传统的算法表示法,它利用几何图形的框来代表各种不同性质的操作,用流程线来指示算法的执行方向。由于它简单直观,所以应用广泛,特别是在早期语言阶段,只有通过流程图才能简明地表述算法,流程图成为程序员们交流的重要手段,直到结构化的程序设计语言出现,对流程图的依赖才有所降低。
下面介绍常见的流程图符号及流程图的例子。
本章例1 - 1的算法的流程图如图1 - 2所示。本章例1 - 2的算法的流程图如图1 - 3所示。在流程图中,判断框左边的流程线表示判断条件为真时的流程,右边的流程线表示条件为假时的流程,有时就在其左、右流程线的上方分别标注&真&、&假&或&T&、&F&或&Y&、&N&。
另外还规定,流程线是从下往上或从右向左时,必须带箭头,除此以外,都不画箭头,流程线的走向总是从上向下或从左向右。
2. 算法的结构化描述
早期的非结构化语言中都有g o t o语句,它允许程序从一个地方直接跳转到另一个地方去。执行这样做的好处是程序设计十分方便灵活,减少了人工复杂度,但其缺点也是十分突出的,一大堆跳转语句使
得程序的流程十分复杂紊乱,难以看懂也难以验证程序的正确性,如果有错,排起错来更是十分困难。这种转来转去的流程图所表达的混乱与复杂,正是软件危机中程序人员处境的一个生动写照。而结构化程序设计,就是要把这团乱麻理清。
经过研究,人们发现,任何复杂的算法,都可以由顺序结构、选择(分支)结构和循环结构这三种基本结构组成,因此,我们构造一个算法的时候,也仅以这三种基本结构作为&建筑单元&,遵守三种基本结构的规范,基本结构之间可以并列、可以相互包含,但不允许交叉,不允许从一个结构直接转到另一个结构的内部去。正因为整个算法都是由三种基本结构组成的,就像用模块构建的一样,所以结构清晰,易于正确性验证,易于纠错,这种方法,就是结构化方法。遵循这种方法的程序设计,就是结构化程序设计。
相应地,只要规定好三种基本结构的流程图的画法,就可以画出任何算法的流程图。
(1) 顺序结构
顺序结构是简单的线性结构,各框按顺序执行。其流程图的基本形态如图1 - 4所示,语句的执行顺序为:A&B&C。
(2) 选择(分支)结构
这种结构是对某个给定条件进行判断,条件为真或假时分别执行不同的框的内容。其基本形状有两种,如图1-5 a)、b)所示。图1-5 a)的执行序列为:当条件为真时执行A,否则执行B;图1 - 5 b)的执行序列为:当条件为真时执行A,否则什么也不做。
1 、(3) 循环结构循环结构有两种基本形态:w h i l e型循环和d o - w h i l e型循环。
2、a. while 型循环如图1 - 6所示。其执行序列为:当条件为真时,反复执行A,一旦条件为假,跳出循环,执行循环紧后的
b. do-while型循环如图1 - 7所示。
执行序列为:首先执行A,再判断条件,条件为真时,一直循环执行A,一旦条件为假,结束循环,执行循环紧后的下一条语句。
在图1 - 6、图1 - 7中,A被称为循环体,条件被称为循环控制条件。要注意的是:
1) 在循环体中,必然对条件要判断的值进行修改,使得经过有限次循环后,循环一定能结束,如图1 - 3中的i = i - 1。2) 当型循环中循环体可能一次都不执行,而直到型循环则至少执行一次循环体。3) 直到型循环可以很方便地转化为当型循环,而当型循环不一定能转化为直到型循环。
例如,图1 - 7可以转化为图1 - 8。
2 用N-S图描述算法
N - S图是另一种算法表示法,是由美国人I . N a s s i和B . S h n e i d e r m a n共同提出的,其根据是:既然任何算法都是由前面介绍的三种结构组成,所以各基本结构之间的流程线就是多余的,因此,N - S图也是算法的一种结构化描述方法。
N - S图中,一个算法就是一个大矩形框,框内又包含若干基本的框,三种基本结构的N - S 图描述如下所示:
1. 顺序结构如图1 - 9所示,执行顺序先A后B。
2. 选择结构
对应于图1 - 5的N - S图为图1 - 1 0。图1-10 a)条件为真时执行A,条件为假时执行B。图1 - 1 0 b )条件为真时执行A,为假时什么都不做。
3. 循环结构
1) while型循环的N - S图如图1 - 11所示,条件为真时一直循环执行循环体A,直到条件为假时才跳出循环。
2) do-while型循环的N - S图如图1 - 1 2,一直循环执行循环体A,直到条件为假时才跳出循环。
本章例1 - 1的N - S图如图1 - 1 3,例1 - 2的N - S图如图1 - 1 4。应该说,N - S图比流程图更直观易懂,而且相对简练一些。
3 用PAD图描述算法
PA D(Problem Analysis Diagram),是近年来在软件开发中被广泛使用的一种算法的图形表示法,与前述的流程图、N - S图相比,流程图、N - S图都是自上而下的顺序描述,而PA D图除了自上而下以外,还有自左向右的展开,所以,如果说流程图、N - S图是一维的算法描述的话,则PA D图就是二维的,它能展现算法的层次结构,更直观易懂。
下面是PA D图的几种基本形态:
1. 顺序结构:
如图1 - 1 5所示。
2. 选择结构
(1) 单分支选择,条件为真执行A,如图1-16 a)。
(2) 两分支选择,如图1-16 b),条件为真执行A,为假执行B。
(3) 多分支选择,如图1-16 c),当I = I1时执行A,I= I2时执行B,I = I3时执行C,I = I4时执行D。
3. 循环结构
如图1 - 1 7所示。图1-17 a)为w h i l e型循环,图1-17 b)为d o - w h i l e型循环。
本章例1 . 1的PA D图如图1 - 1 8,例1 - 2的PA D图如图1 - 1 9。
视频教程列表
文章教程搜索
输入您的搜索字词
提交搜索表单
C语言程序设计推荐教程
tel:<font color="#FF30058Prim算法(一)之 C语言详解 - 如果天空不死 - 推酷
Prim算法(一)之 C语言详解 - 如果天空不死
本章介绍普里姆算法。和以往一样,本文会先对普里姆算法的理论论知识进行介绍,然后给出C语言的实现。后续再分别给出C++和Java版本的实现。
.普里姆算法介绍
.普里姆算法图解
.普里姆算法的代码说明
.普里姆算法的源码
转载请注明出处:
更多内容:
普里姆算法介绍
普里姆(Prim)算法,和克鲁斯卡尔算法一样,是用来求加权连通图的最小生成树的算法。
对于图G而言,V是所有顶点的集合;现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最小生成树中的边。 从所有u?U,v?(V-U) (V-U表示出去U的所有顶点)的边中选取权值最小的边(u, v),将顶点v加入集合U中,将边(u, v)加入集合T中,如此不断重复,直到U=V为止,最小生成树构造完毕,这时集合T中包含了最小生成树中的所有边。
普里姆算法图解
以上图G4为例,来对普里姆进行演示(从第一个顶点A开始通过普里姆算法生成最小生成树)。
:V是所有顶点的集合,即V={A,B,C,D,E,F,G};U和T都是空!
:将顶点A加入到U中。
&&&&此时,U={A}。
:将顶点B加入到U中。
&&&&上一步操作之后,U={A}, V-U={B,C,D,E,F,G};因此,边(A,B)的权值最小。将顶点B添加到U中;此时,U={A,B}。
:将顶点F加入到U中。
&&&&上一步操作之后,U={A,B}, V-U={C,D,E,F,G};因此,边(B,F)的权值最小。将顶点F添加到U中;此时,U={A,B,F}。
:将顶点E加入到U中。
&&&&上一步操作之后,U={A,B,F}, V-U={C,D,E,G};因此,边(F,E)的权值最小。将顶点E添加到U中;此时,U={A,B,F,E}。
:将顶点D加入到U中。
&&&&上一步操作之后,U={A,B,F,E}, V-U={C,D,G};因此,边(E,D)的权值最小。将顶点D添加到U中;此时,U={A,B,F,E,D}。
:将顶点C加入到U中。
&&&&上一步操作之后,U={A,B,F,E,D}, V-U={C,G};因此,边(D,C)的权值最小。将顶点C添加到U中;此时,U={A,B,F,E,D,C}。
:将顶点G加入到U中。
&&&&上一步操作之后,U={A,B,F,E,D,C}, V-U={G};因此,边(F,G)的权值最小。将顶点G添加到U中;此时,U=V。
此时,最小生成树构造完成!它包括的顶点依次是:
A B F E D C G
普里姆算法的代码说明
以&邻接矩阵&为例对普里姆算法进行说明,对于&邻接表&实现的图在后面会给出相应的源码。
1. 基本定义
// 邻接矩阵
typedef struct _graph
char vexs[MAX];
// 顶点集合
int matrix[MAX][MAX]; // 邻接矩阵
}Graph, *PG
// 边的结构体
typedef struct _EdgeData
// 边的起点
// 边的终点
// 边的权重
Graph是邻接矩阵对应的结构体。
vexs用于保存顶点,vexnum是顶点数,edgnum是边数;matrix则是用于保存矩阵信息的二维数组。例如,matrix[i][j]=1,则表示&顶点i(即vexs[i])&和&顶点j(即vexs[j])&是邻接点;matrix[i][j]=0,则表示它们不是邻接点。
EData是邻接矩阵边对应的结构体。
2. 普里姆算法
* prim最小生成树
* 参数说明:
G -- 邻接矩阵图
start -- 从图中的第start个元素开始,生成最小树
void prim(Graph G, int start)
int min,i,j,k,m,n,
int index=0;
// prim最小树的索引,即prims数组的索引
char prims[MAX];
// prim最小树的结果数组
int weights[MAX]; // 顶点间边的权值
// prim最小生成树中第一个数是&图中第start个顶点&,因为是从start开始的。
prims[index++] = G.vexs[start];
// 初始化&顶点的权值数组&,
// 将每个顶点的权值初始化为&第start个顶点&到&该顶点&的权值。
for (i = 0; i & G. i++ )
weights[i] = G.matrix[start][i];
// 将第start个顶点的权值初始化为0。
// 可以理解为&第start个顶点到它自身的距离为0&。
weights[start] = 0;
for (i = 0; i & G. i++)
// 由于从start开始的,因此不需要再对第start个顶点进行处理。
if(start == i)
min = INF;
// 在未被加入到最小生成树的顶点中,找出权值最小的顶点。
while (j & G.vexnum)
// 若weights[j]=0,意味着&第j个节点已经被排序过&(或者说已经加入了最小生成树中)。
if (weights[j] != 0 && weights[j] & min)
min = weights[j];
// 经过上面的处理后,在未被加入到最小生成树的顶点中,权值最小的顶点是第k个顶点。
// 将第k个顶点加入到最小生成树的结果数组中
prims[index++] = G.vexs[k];
// 将&第k个顶点的权值&标记为0,意味着第k个顶点已经排序过了(或者说已经加入了最小树结果中)。
weights[k] = 0;
// 当第k个顶点被加入到最小生成树的结果数组中之后,更新其它顶点的权值。
for (j = 0 ; j & G. j++)
// 当第j个节点没有被处理,并且需要更新时才被更新。
if (weights[j] != 0 && G.matrix[k][j] & weights[j])
weights[j] = G.matrix[k][j];
// 计算最小生成树的权值
for (i = 1; i & i++)
min = INF;
// 获取prims[i]在G中的位置
n = get_position(G, prims[i]);
// 在vexs[0...i]中,找出到j的权值最小的顶点。
for (j = 0; j & j++)
m = get_position(G, prims[j]);
if (G.matrix[m][n]&min)
min = G.matrix[m][n];
// 打印最小生成树
printf(&PRIM(%c)=%d: &, G.vexs[start], sum);
for (i = 0; i & i++)
printf(&%c &, prims[i]);
printf(&\n&);
普里姆算法的源码
这里分别给出&邻接矩阵图&和&邻接表图&的普里姆算法源码。
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见  个人觉得汉诺塔这个递归算法比电子老鼠的难了一些,不过一旦理解了也还是可以的,其实网上也有很多代码,可以直接参考。记得大一开始时就做过汉诺塔的习题,但是那时代码写得很长很长,也是不理解递归的结果。现在想起来汉诺塔的算法就3个步骤:第一,把a上的n-1个盘通过c移动到b。第二,把a上的最下面的盘移到c。第三,因为n-1个盘全在b上了,所以把b当做a重复以上步骤就好了。所以算法看起来就简单多了。不过,思考过程还是很痛苦的,难以理解。递归中会保存数据的好处在这里又得到体现,太神奇了。
汉诺塔代码如下:
#include&stdio.h&
void move(int n,char a,char b,char c)
printf("\t%c-&%c\n",a,c);
//当n只有1个的时候直接从a移动到c
move(n-1,a,c,b);
//第n-1个要从a通过c移动到b
printf("\t%c-&%c\n",a,c);
move(n-1,b,a,c);
//n-1个移动过来之后b变开始盘,b通过a移动到c,这边很难理解
printf("请输入要移动的块数:");
scanf("%d",&n);
move(n,'a','b','c');
这边还找到一个ppt有助于对汉诺塔的理解,可以来看看
阅读(...) 评论()

我要回帖

更多关于 c语言经典算法 的文章

 

随机推荐