数据
数据是描述客观事物的数值,字符以及能输入机器且能被处理的各种符号集合
数据项
数据项具有原子性, 是不可分割的最小数据单位
数据元素
数据元素是数据的基本单位,是数据集合的个体, 通常由若干个数据项组成,在计算机程序中作为一个整体来进行处理
数据对象
数据对象是性质相同的数据元素的集合,是数据的子集
数据结构
数据结构是指相互之间存在一种或多种特定关系的数据的集合
数据结构=逻辑结构+存储结构+(在存储结构上)运算/操作
数据的逻辑结构
分类1:线性结构和非线性结构
- 线性结构:有且只有一个开始节点和一个终端节点,并且所有的节点都最多只有一个前驱和一个后继
- 非线性结构:一个元素可能对应多个直接前驱和多个直接后继
分类2:集合结构,线性结构,树状结构,网格结构
- 集合结构:确定性,唯一性,无序性
- 线性结构:数据元素之前存在着一对一的线性关系
- 树状结构:除了一个元素外,每个元素有且仅有一个直接的前驱元素,但是可以有多个后继元素
- 网格结构:元素之间是多对多的关系,每个元素可以有多个直接前驱元素,也可以有多个直接后继元素
数据的存储结构
分类:顺序存储,链式存储,索引存储, 散列存储
- 顺序存储:把逻辑上相邻的节点存储在物理位置上相邻的存储单元种,节点之间的逻辑关系由存储单元的邻接关系来提现
- 链式存储:数据元素的存储对应的是不连续的存储空间,每个存储节点对应一个需要存储的数据元素
- 索引存储:除建立存储点信息外,还建立附加的索引表来标识节点的地址
- 散列存储:根据节点的关键字直接计算出该节点的存储地址
逻辑结构唯一,存储结构不唯一,运算依赖于存储结构
算法的定义、基本性质以及算法分析的基本概念
算法的定义:是为了求解问题给出的有限指令序列,每条指令表示一个或多个操作。
算法的基本性质:
- 输入:一个算法有0个或多个输入,这些输入取自某个特定对象的集合。
- 输出:一个算法有一个或多个输出,这些输出是同输入具有某种特定关系的量
- 确定性:算法中每一条指令必须有确切的含义,不具有二义性
- 可行性:算法中描述的操作都可以用已经实现的运算执行有限次来实现。
- 有穷性:一个算法必须能够在执行又穷步骤后结束,并且每一步都能在又穷时间内完成。
算法分析:
一个用高级语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:
- 算法采用的策略、方法;
- 编译产生的代码质量;
- 问题的输入规模;
- 机器执行指令的速度。
一个算法是由控制结构(顺序、分支和循环3种)和原操作(指固有数据类型的操作)构成的,则算法时间取决于两者的综合效果。为了便于比较同一个问题的不同算法,通常的做法是,从算法中选取一种对于所研究的问题(或算法类型)来说是基本操作的原操作,以该基本操作的重复执行的次数作为算法的时间量度。
算法运行所需要的时间称为时间复杂性;算法运行所需要的辅助空间称为空间复杂性。算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。而度量一个程序的执行时间通常有两种方法。
- 事前估计法:时间按复杂度估计。抽象过程如下:算法运行时间=每条语句执行时间之和 =》每条语句的执行次数之和 =》基本语句的执行次数 =》基本语句执行次数的数量级 =》大O号表示。常见的时间复杂度如下Ο(1)<Ο(log₂n)<Ο(n)<Ο(nlog₂n)<Ο(n²)<Ο(n³)<…<Ο(2ⁿ)<Ο(n!)
描述 | 增长的数量级 | 典型代码 | 说明 | 举例 |
常数级别 | Ο(1) | a=b+c | 普通语句 | 将两个数相加 |
对数级别 | Ο(log₂n) | 二分查找 | 二分查找 | 二分查找 |
线性级别 | Ο(n) | for(int i=0;i<N;i++){ } | 循环 | 找出最大元素 |
线性对数级别 | Ο(nlog₂n) |
| 分治 | 归并排序 |
平方级别 | Ο(n²) | for(int i=0;i<N;i++){ for(int j=0;j<N;j++){ } } | 双层循环 | 检查所有元素对 |
立方级别 | Ο(n³) | 代码省略 | 三层循环 | 检查所有三元组 |
指数级别 | Ο(2ⁿ) | 穷举查找 | 检查所有子集 |
- 事后统计法:程序运行测试。 比如在调用某个方法的前后打印当前时间,以此来判断该方法执行耗时,缺点是需要编写特定程序,且硬件环境影响测试结果(比如服务器与pc机器性能不同,同样的算法在这2者之间运行的时间是不一样的)
时间复杂度
(1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。
(2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
空间复杂度
算法的存储量包括:
- 程序本身所占空间
- 输入数据所占空间
- 辅助变量所占空间
输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间。
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。
一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。存储算法本身所占用的存储空间与算法书写的长短成正比,要压缩这方面的存储空间,就必须编写出较短的算法。
@TODO-PAN