一、绪论
数据结构是相互之间存在一种或多种的关系的数据元素的集合。
1. 逻辑结构与物理结构
按照视点不同,可以分为逻辑结构和物理结构:
- 逻辑结构:
数据对象中数据元素间的相互关系。
可分为4种 集合结构、线性结构、树形结构、图形结构。 - 物理结构:
- 指逻辑结构在计算机中的存储形式。
两种: 顺序存储、链式存储。
顺序:数据的逻辑关系和物理关系一致。
链式:存放在任意的存储单元里,存储单元可以连续,可以不连续。
2. 数据类型
- 原子类型:不可以再分解的基本类型,整型、实型、字符型等。
- 结构类型:可以再分解:例如整形数组由整形数据组成。
抽象:抽取出事物具有的普遍性的本质。
- 抽象数据类型(ADT):一个数学模型及定义在该模型上的一组操作。
二、算法
1. 算法的特性
五个特性:
- 输入:0或者多个
- 输出:一个或多个
- 有穷性:自动结束,不出现无限循环,且每步骤在可接受的时间内完成
- 确定性
- 可行性
2. 设计要求
- 正确性
- 可读性
- 健壮性
- 时间效率高,存储量低
3. 算法效率度量方法
- 事后统计
- 事前分析估算
程序运行时间依赖于算法好坏与问题的输入规模(输入量的多少)
4. 函数的渐进增长
判断谋算法效率,函数中的常数和其它次要项常常可忽略,而更应该关注主项(最高次项)的阶数。
5. 算法时间复杂度O()
1. 推导方法
- 用常数1取代运行时间中的所有加法常数
- 修改后的运行次数函数中,只保留最高阶
- 如果最高阶存在且不是1,则去除与这个项相乘的常数
2. 分类
1. 常数阶
对于分支结构,无论真假,执行次数恒定,不随着n变化。因此单纯分支结构时间复杂度为O(1)
2. 线性阶
分析循环结构运行情况,例如如下为O(n)
int i;
for (i=0;i<n;i++)
3. 对数阶
例如:
int m=1;
while (m<n) {
m = m*2;
}
由于2^(x)=n, 得到 x = l o g 2 n x=log_2 n x=log2n, 复杂度为O(logn)
4. 平方阶
常常为循环嵌套,分析多层循环
例如:
int i,j;
for (i=0;i<n;i++) {
for (j=0;j<n;j++) {
}
}
复杂度为O(n*n)
int i,j;
for (i=0;i<n;i++) {
for (j=0;j<m;j++) {
}
}
复杂度为O(n*m)
int i,j;
for (i=0;i<n;i++) {
for (j=i;j<n;j++) {
}
}
复杂度为n+(n-1)+(n-2)+…+1
5. 总结
常用时间复杂度从小到大为:
O
(
1
)
<
O
(
l
o
g
n
)
<
O
(
n
)
<
O
(
n
l
o
g
n
)
<
O
(
n
2
)
<
O
(
n
3
)
<
O
(
2
n
)
<
O
(
n
!
)
<
O
(
n
n
)
O(1)<O(logn)<O(n)<O(nlogn)<O(n^{2})<O(n^{3})<O(2^{n})<O(n!)<O(n^{n})
O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
6. 最坏情况与平均情况
最坏情况: 运行时间的保证
平均情况:期望的运行时间
7. 空间复杂度 S()
S(n)=O(f(n)),n为问题规模,f(n)为语句关于n所占存储空间的函数。
当不用限定词直接说复杂度时,一般指时间复杂度。
(写代码时可以用空间换时间)