目录
用计算机解决问题
用计算机解决问题的过程分为两个阶段:程序开发者针对要解决的问题开发出相应的程序,使用者运行程序处理问题的具体实例,完成具体计算。
考虑一个计算问题时,要注意三个概念:
- 问题:一个问题W是需要解决(需要用计算求解)的一个具体需求。
- 问题实例:问题W的一个实例w是该问题的一个具体例子。
- 算法:解决问题W的一个算法A,是对一种计算过程的严格描述。对W的任何一个实例w,实施算法A描述的计算过程,就能得到w的解。
算法的性质
算法是对计算过程的严格描述。
- 有穷性:一个算法的描述应该由优先多条指令或语句构成。
- 能行性:算法中所描述的操作过程可以完全机械地进行。
- 确定性:根据算法的描述将产生出唯一的确定的一个动作序列。
- 终止性:对问题的任何实例,算法产生的动作序列是有穷的,或者终止并给出该问题实例的解;或者终止并指出给定的输入无解。
- 输入/输出:有明确定义的输入和输出。
算法的描述
- 采用自然语言描述,比较容易阅读、理解。
- 采用在自然语言描述中结合一些数学记法或公式的描述形式。
- 采用严格定义的形式化记法形式描述。如图灵机模型。
- 用类似某种编程语言的形式描述算法过程,其中参杂使用一些数学符号和记号,用于描述一些细节和具体操作。
- 采用某种伪代码形式,结合编码语言的常用结构、形式化的数学记法代表的严格描述和自然语言。
算法设计
算法设计中一些常见的通用想法
- 枚举法
- 贪心法:根据问题的信息尽可能做出部分的解,并基于部分解逐步扩充得到完整的解。
- 分治法:把复杂问题分解为相对简单的子问题。
- 回溯法(搜索法)
- 动态规划法
- 分支限界法
算法分析的主要任务就是弄清算法的资源消耗,最重要的作用是作为评价算法的一种标准。
时间代价和空间代价
循环语句的时间代价:
- 一个循环的时间代价=循环次数x每次执行的简单语句数目
- 多个并列循环的时间代价=每个循环的时间代价总和
- 多层嵌套循环的时间代价=每层循环的时间代价之积
空间代价:
当问题的规模以某种单位从1增大到n时,解决这个问题的算法在执行时所占用的存储空间也以某种单位从1增加到S(n),S(n)即为该算法的空间代价。
数据结构
定义:
数据结构是相互之间存在一种或多种特定关系的数据元素的集合,换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。通俗讲,就是研究数据怎么储存的。
对于存储数据,要根据数据本身以及其他相关要求,看数据准备怎么用,然后考虑其存储方式。
数据结构相当于一个统称,包含数据、链表、栈和队列等等,不同的数据结构有特定的用途,有自己的特点,这些特点就是规定如果数据选择了这种数据结构来存储,就要按照它的要求内存中存放,比如选择了数组,那么数据要在内存中连续存储,一个挨着一个,不能乱;如果选择了链表,那么内存中不要求非得连续存储,随意、有空地就可以存储。
可以把数据结构想像成一个容器,这里用来存储数据,而这些容器形状各异,选择了不同的容器(数据结构),那么就意味着数据的存储形式是不同的。
数据结构总的来说分为3大类:
- 线性表,也就是数组、链表、栈和队列;
- 树结构,包括普通树、二叉树、红黑树等等;
- 图存储结构
典型数据结构:
- 集合结构:数据元素之间没有需要关注的明确关系。
- 序列结构:数据元素之间有一种明确的先后关系(顺序关系)。存在一个排位在最前的元素,处理最后的元素外,每个元素都有唯一的后继元素,所有元素排列成一个线性序列。也称为线性结构。其特点是每个元素只有(最多)一个后继,且有方向。
- 层次结构:数据元素分属于一些不同的层次,一个上层元素可以关联着一个或者多个下层元素。只从上层到下层(通常也允许跨层次)。
- 树状结构:层次结构中最简单的一种关系是树形结构,其特点是在一个树形结构中只有一个最上层数据元素,称为根,其余元素都是根的直接或间接关联的下层元素。树形数据结构简称为树,相应的复杂数据对象称为树形对象。
- 图结构:数据元素之间可以由任意复杂的相互联系。数学领域中的图概念是这类复杂结构的抽象,因此人们把这样的结构称为图结构,把这样的复杂对象称为图对象。
内存单元和地址
计算中直接使用的数据保存在计算机的内存储器(简称内存)。内存是CPU可以直接访问的数据存储设备。
内存的基本结构是线性排列的一批存储单元。每个单元的大小相同,可以保存一个单位大小的数据。在目前最常见的计算机中,一个单元可以保存一个字节(8位二进制代码)的数据。因此存放一个整数或浮点数,需要连续的几个单元。例如标准的浮点数需要8个单元。
内存单元具有唯一编号,称为单元地址,简称地址。
数量级函数
基本操作数量函数T(n)的精确值并不是特别重要,重要的是T(n)中起决定性因素的主导部分
大O表示法
数量级函数描述了T(n)中随n增加而增加速度最快的主导部分,称作“大O”表示法,记作O(f(n)),其中f(n)表示T(n)中的主导部分。大O表示法,表示了所有上限中最小的那个上限。
确定运行时间数量级大O的方法:
例1:T(n)=1+n
在n增大时,n作为主要部分,运行时间数量级就是O(n)
例2:T(n)=5n²+27n+1007
当n增大时,n²作为主要部分,运行时间数量级就是O(n²)
影响算法运行时间的其他因素:
有时决定运行时间的不仅是问题规模,某些具体数据也会影响算法运行时间(分为最好、最差和平均情况,平均状况体现了算法的主流性能。
对算法的分析要看主流,而不被某几种特定的运行状况所迷惑。
常见的大O数量级函数:
通常当n较小时,难以确定其数量级,当n增长到较大时,容易看出其主要变化量级
f(n) | 名称 |
---|---|
1 | 常数 |
log(n) | 对数 |
n | 线性 |
n*log(n) | 对数线性 |
n² | 平方 |
n³ | 立方 |
2∧n | 指数 |