数据结构概论
数据
数据是客观事物的符号表示。在计算机科学中,数据是指所有能输入到计算机中,并被计算机程序处理的符号总称。它是能够被计算机识别、存储和加工处理的信息的载体。
数据元素
数据元素是数据的基本单位,有时一个数据元素可以由若干个数据项组成。比如学生是一个数据元素,学生里面有姓名、学号和班级这样的数据项。数据项是具有独立含义的最小数据标识单位。
数据结构
数据结构是计算机中存储、组织数据的方式。根据数据元素之间关系的不同,可以分为下列四类基本结构
集合
数据元素之间除了属于同一个集合的关系外,别无其他逻辑关系。数据结构课程较少讨论。
线性结构
数据元素存在一对一的关系。
线性结构中
第一个结点没有前驱结点,其余每个结点有且只有一个前驱结点
最后一个结点没有后继结点,其余每个结点有且只有一个后继结点
树形结构
数据元素存在一对多的关系。
树形结构中
根结点没有前驱结点,其余每个结点有且只有一个前驱结点
叶子结点没有后继结点,其余每个结点的后继结点可以是任意多个
图形结构
数据元素存在多对多的关系。
每个结点的前驱结点和后继结点可以是任意多个。
数据结构包含下列三个方面的内容
逻辑结构
逻辑结构是对数据之间关系的描述,逻辑结构在形式上用二元组表示
B
=
{
K
,
R
}
B = \{K, R\}
B={K,R}
K表示数据元素的有穷集合
R表示数据元素之间关系的有穷集合
某数据逻辑结构如下
B
=
{
K
,
R
}
B = \{K,R\}\\
B={K,R}
K
=
{
1
,
2
,
3
,
4
}
K = \{1,2,3,4\}\\
K={1,2,3,4}
R
=
{
<
1
,
2
>
,
<
1
,
3
>
,
<
3
,
4
>
}
R = \{<1,2>,<1,3>,<3,4>\}\\
R={<1,2>,<1,3>,<3,4>}
存储结构
数据的存储方式有四种
- 顺序存储
- 链式存储
- 索引存储
- 散列存储
顺序存储
顺序存储方式是把逻辑上相邻的结点存储在物理上相邻的存储单元里,结点之间的关系由存储单元的邻接关系来体现。
优点 | 缺点 |
---|---|
占用最少的存储空军 | 只能使用相邻的一整块存储单元,可能产生较多的碎片现象 |
链式存储
将结点所占的存储空间分为两部分
数据域 | 指针域 |
---|---|
存放结点本身的信息 | 存放后继结点的地址 |
优点 | 缺点 |
---|---|
不会出现碎片现象 | 指针域的存在让结点占用了更多的存储空间 |
索引存储
用结点的索引号来确定结点存储地址
优点 | 缺点 |
---|---|
检索速度快 | 附加的索引表占用了较多的存储空间 |
进行增加和删除操作时要同步修改索引表,效率较低 |
散列存储
根据结点的值确定它的存储地址
优点 | 缺点 |
---|---|
检索、增加和删除结点效率很高 | 采用不好的散列函数可能会出现地址冲突的情况,解决冲突需要额外的时间和空间开销 |
数据运算
对数据进行操作,不仅需要加减乘除这样的原操作,还经常涉及到算法,算法的实现与数据的存储结构密切相关
算法
算法是对特定问题求解步骤的一种描述,算法是指令的有限序列,每一条指令表示一个或多个操作
算法的五大重要特征
有穷性
对于合法的输入,执行有穷步之后停机
void func(void) {
int n = 2;
while (n % 2 == 0) {
n += 2; //死循环 违反了有穷性特征
printf("%d\n", n);
}
}
确定性
算法中每一条指令不能有歧义
可行性
可通过基本运算有限次执行来实现。
int func( int x ) {
return x / 0; //除零错误 违反了可行性特征
}
输入性
有零个或多个输入
输出性
有一个或多个输出