C - Language | Algorithm
算法是解决一个问题,完整的步骤描述,是解决问题的策略、规则、方法,是求解特定问题的一组有限的操作序列(算法用来解决问题)
程序应该包括对数据的描述和对数据的操作。数据的描述就是在程序中要指定数据结构,即数据的类型和数据的组织形式。对数据的操作也就是对数据进行操作的,就是算法(算法实现数据结构)
//算法最终服务于程序设计
//算法+数据结构=程序(如何实现+实现结果)
算法分为两大类,数值运算算法和非数值运算算法
- 数值运算算法:用于解决科学于工程计算方面的算法(数值积分、微分方程、线性方程、代数方程)
- 非数值运算算法:解决数据处理方面的算法(查找算法、排序算法、遍历算法)
//计算机在非数值运算方面的应用远远超过了在数值运算方面的应用
有穷性
算法是一组有限的操作序列,必须在执行有限步骤后结束,且无论是哪一个步骤,都应在有限的时间内完成并结束,而不是无限的执行下去
确定性
算法的每一个部分或步骤都应该有明确的定义,且具有相对应的意义,每一个过程都不能有二义性,并且执行过程皆有严格的规定
可行性
算法中的每一个部分或步骤,都必须可以有效的运行,并且得到切实的结果
输入
算法可以没有输入、也可以有多个输入。输入是在执行算法时从外界取得的必要信息,即算法所需的初始量
输出
算法可以有一个或多个输出,输出就是算法运算的最终结果。
算法优劣
若要判断一个算法的好坏,需要从至少四个方面来分析,包括正确性、可读性、健壮性、时间复杂度与空间复杂度
- 正确性
- 可读性
- 健壮性
- 时间复杂度
- 空间复杂度
正确性
正确性是指算法能满足具体问题的要求(对任何合法的输入,算法都会得到正确的结果)
可读性
可读性是指算法被理解的难易程度。难于理解的算法,其对修改、扩展维护都不利(算法应该简单明了)
健壮性
面对非法输入的数据时,算法是否能做出相应的响应,而不会错误输入造成程序瘫痪
时间复杂度
时间复杂度就是算法运行所需要的时间(以及语句执行次数)
时间复杂度与很多方面的因素相关
- 问题规模的大小
- 源程序编译功能的强弱,以及编译后机器代码质量的优劣
- 执行一条目标指令所需的时间
- 程序中语句的执行次数,一个好的算法,应该使程序中语句的执行次数尽量最少
由于不同的计算机语言实现效率与不同的编译器效率都不尽相同,所以时间复杂度一般通过程序中语句的执行次数来作为度量标准
空间复杂度
空间复杂度是指算法所需要多少的存储空间,一个好的算法应该尽量占用更好的存储空间(占用更少的内存)
算法设计
算法设计研究的是对特定类型的问题,设计出求解步骤
算法分析
算法分析讨论的是算法步骤的正确性和复杂性
算法描述
算法描述是对求解步骤的表达,常用的方法有" 自然语言 "、" 流程图 "、" N-S流程图 "和" 伪代码 "等
- 自然语言
- 流程图
- N-S流程图
- 伪代码
自然语言
自然语言就是使用日常用语,通俗易懂的对算法进行描述
自然语言的优势是简单、通俗易懂,缺点是容易产生歧义、效率低等
流程图
流程图通过" 图框 "来代表不同性质的操作,用" 流程线 "来指示算法的执行方向
算法流程图有7种基础图框或符号
流程图符号
-
起止框(圆弧形框)
用来标识算法的开始和结束
-
输入输出框(不等边菱形框)
用来表示程序的各种输入或输出(常量、变量、表达式等)
-
判断框(等边菱形框)
用于对一个给定的条件进行判断,根据给定的条件是否成立来决定如何执行后面相应的操作
-
处理框(矩形框)
用来处理运算或比较式子(表达式等)
-
注释框(半开口矩形虚线)
用来解释说明
-
流程线(指向线)
连接图框,是流程图必不可少的部分之一
-
连接点(圆圈)
将画在不同地方的流程线连接起来
流程图结构
算法流程图有三种基本结构,包括" 顺序结构 "、" 选择结构 "、" 循环结构 "
三种基本结构之间可以包含、可以并列、但不允许交叉,不允许从一个结构直接转到另一个结构的内部
-
顺序结构
顺序结构是简单的线性结构,各操作按照先后顺序执行,这个结构只有一个入口点和一个出口点
-
选择结构(分支结构)
选择结构必须包含至少一个判断框
根据判断条件,执行不同的分支流程
-
循环结构
循环结构是程序反复的循环执行一系列操作,知道满足一定条件时,才终止循环
循环结构也必须至少包含一个判断框
按照判断条件出现的位置,循环结构可细分为" 当型循环结构 "、" 直到型循环结构 "
当型循环结构 直到型循环结构
N-S流程图
N-S流程图的意义在于,既然任何算法基本都由3种基本结构组成(顺序结构、选择结构、循环结构),那么个基本结构之间的流程线就可以是多余的。因此N-S流程图等同于去掉了流程线的流程图,是结构化编程种的一种可视化建模
N-S流程图将全部的算法写在一个矩形框内,遂N-S流程图又称" 盒图 "
用N-S流程图作为详细设计的描述手段时,常需用两个盒子:数据盒和模块盒,前者描述有关的数据,包括全程数据、局部数据和模块界面上的参数等,后者描述执行过程
//N-S流程图的全称是" Nassi Shneiderman流程图 ",由此流程图的两位发明者名字共同组成
顺序结构 | |
---|---|
选择结构 | |
多分支结构 | |
当型循环结构 | |
直到型循环结构 |
伪代码
伪代码(Pseudocode)是介于自然语言和机器语言之间用文字和符号来描述算法的,类似于一篇文章,每一行表示一个操作,不使用图形符号,具体写法无规范可自定义书写标准
伪代码便于向机器语言过渡
C语言代码 | 伪代码 |
---|---|
结构化程序设计
描述任何问题解决方案的操作序列,只需要用到" 顺序结构 "、" 选择结构 "、" 循环结构 "三种基本结构
结构化设计是程序设计所必须的思维方式之一
结构化程序设计应采用从上至下、逐步细化的方法展开,细化过程中应当充分运用前面的控制结构和模块划分原则
结构化程序设计应分为包括" 自顶向下、逐步细化 "、" 模块化设计 "、" 结构化编码 "等三个步骤
-
自顶向下、逐步细化
全局思考,将问题分为几个部分,每一部分又分为几个模块,每个模块包括几个功能,每个功能又应该设计什么函数来实现
-
模块化设计
函数模块设计应采用" 高内聚 "、" 低耦合 "的设计思路
高内聚是指模块内部所设计的功能越单一越好,这样模块功能明确,方便维护
低耦合是指模块与模块之间的联系越少越好,这样程序中模块的独立性就越强,更方便维护
-
结构化编码
将程序按照鲜明的层次结构进行设计