1. 数据结构的基本概念
1.1 常见术语
- 数据: 信息的载体,能输入到计算机并被计算机程序识别和处理的符号集合(包括数、字符等)。
- 数据元素: 数据的基本单位,由若干数据项(不可分割的最小单位)组成。
如:学生信息作为一种数据元素,可以由学号、姓名、性别等数据项组成。 - 数据对象: 具有相同性质的数据元素的集合。
如:自然数就可以看成是一种数据对象,N = {0,1,2… }。 - 数据类型:由值的集合和定义在该集合的一组操作的总称。
- 原子类型:值不可再分解。如 int 型,常见的操作有: 四则运算,模运算等。
- 结构类型:值可以分解为若干分量,这些分量可以是非结构的原子类型,也可以是结构类型。
- 抽象数据类型(Abstract Data Type, ADT): 由问题抽象出的一种数学模型和定义在该数学模型上的一组操作(常见操作为构造、查找、修改等)。抽象数据类型的定义只取决于它的逻辑特性,与其在计算机内部如何表示和实现无关。
ADT 抽象数据类型名 { 数据对象:<数据对象的定义> 数据关系:<数据关系的定义> 基本操作:<基本操作的定义> }
- 数据结构: 相互之间存在一种或多种特定关系的数据元素的集合。包括三个方面的内容(三要素):逻辑结构、存储结构(物理结构)、运算规则。
- 逻辑结构:指数据元素之间的逻辑关系,如线性和非线性。
- 存储结构: 指数据元素在计算机中实际的表示,包括数据元素自身的表示和元素之间逻辑关系的表示。常见的存储结构:顺序存储、链式存储、索引存储、散列存储。
- 运算规则: 针对数据元素的运算,包括定义和实现两部分。定义是针对逻辑结构,指出需要的运算功能;实现是针对存储结构,指出运算功能具体的操作步骤。
2. 算法的基本概念
2.1 定义
- 算法是对特定问题求解步骤的描述,在计算机中表现为指令的有限序列,其中每条指令表示一个 或多个操作。
2.2 特性
- 有穷性: 一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。
- 确定性: 算法中每条指令必须有确切的含义,对于相同的输入只能得到相同的输出。
- 可行性: 算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
- 输入输出: 一个算法有零个或多个输入,有一个或多个输出。
2.3 设计要求
- 正确性: 算法应该能正确的反映问题,并能得到正确的答案。
- 可读性: 算法应该具有良好的可读性,便于理解和交流。
- 健壮性: 算法应该能对非法输入做出适当的反应或处理,而不是产生莫名其妙的结果。
- 高效率低存储: 算法应该尽量满足执行时间短,同时执行过程中所使用的存储空间少。
2.4 算法效率的度量
- 时间复杂度: 算法时间的度量,记作: T(n) = O( f(n) )。其中 T(n) 表示语句总的执行次数,是关于问题规模 n的函数,f(n) 是问题规模 n 的某个函数,随着问题规模 n 增大,算法执行时间的增长率和 f(n) 的增长率相同。
- 最好时间复杂度: 在最好情况下,算法运行的时间。
- 平均时间复杂度: 所有情况等概率出现,算法的期望运行时间。
- 最坏时间复杂度: 在最坏情况下,算法运行的时间。
一般总是考虑最坏时间复杂度,以保证算法运行时间不会比它更长。
常用的方法: 列出最深层循环的一条语句的执行次数 x 与问题规模 n 的函数关系,求出 x。
如下:
先建立最内层循环 i *= 2 这条语句执行次数int function(int n) { int i = 1; while (i > n) { i *= 2; } return i; }
x
与问题规模n
的函数关系:
2 x = n 2^x = n 2x=n
再解出x
x = log 2 n x = \log_2{n} x=log2n ,则该算法的时间复杂度为 O ( log 2 n ) O(\log_2{n}) O(log2n)。
- 加法、乘法规则
- 加法规则: T ( n ) = T 1 ( n ) + T 2 ( n ) = O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x ( f ( n ) , g ( n ) ) ) T(n) = T_1(n) + T_2(n) = O(f(n)) + O(g(n)) = O(max(f(n), g(n))) T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)))
- 乘法规则:
T
(
n
)
=
T
1
(
n
)
×
T
2
(
n
)
=
O
(
f
(
n
)
)
×
O
(
g
(
n
)
)
=
O
(
f
(
n
)
×
g
(
n
)
)
T(n) = T_1(n) \times T_2(n) = O(f(n)) \times O(g(n)) = O(f(n) \times g(n))
T(n)=T1(n)×T2(n)=O(f(n))×O(g(n))=O(f(n)×g(n))
- 常见的时间复杂度比较
O ( 1 ) < O ( log 2 n ) < O ( n ) < O ( n log 2 n ) < O ( n k ) < O ( 2 n ) < O ( n ! ) < O ( n n ) O(1) < O(\log_2{n}) < O(n) < O(n\log_2{n}) < O(n^k) < O(2^n) < O(n!) < O(n^n) O(1)<O(log2n)<O(n)<O(nlog2n)<O(nk)<O(2n)<O(n!)<O(nn)
- 空间复杂度:算法存储空间的度量,记作:
S
(
n
)
=
O
(
g
(
n
)
)
S(n) = O(g(n))
S(n)=O(g(n))。其中 S(n) 表示算法所用到的存储空间,是关于问题规模
n
的函数。空间复杂度为 O ( 1 ) O(1) O(1) 的算法常称作原地工作,即需要的辅助空间为常量。