数据结构
一、数据结构基本概念
1.广义定义
如何把数据高效储存在计算机的内存中,方便后续进行增、删、改、查操作,特别是在数据量较大的情况下。
2.正式定义
相互之间存在一种或多种特定关系的数据元素的集合。
3.逻辑结构
从人的思维角度分析数据与数据之间的关系:
-
集合结构 - 数据元素同属一个集合,无其他关系
-
线性结构 - 一对一关系,如排队
-
树形结构 - 一对多关系,如目录结构
-
图形结构 - 多对多关系,如地图、网络结构
4.物理结构
将逻辑结构按照某种方式存储在计算机内存中:
-
顺序存储 - 在内存中连续存储,数据存放在连续的存储单元中,逻辑关系和物理关系一致
-
链式存储 - 使用malloc分配内存,在内存中不一定连续存储,存储单元可以连续也可以不连续
5.基本概念详解
数据 (Data)
程序中的输入、输出以及基本操作的对象。在C语言中体现为变量。
数据元素 (Data Element)
描述一个相对完整的事物,包含多个属性(数据项)。在C语言中通常用struct表示。
数据对象 (Data Object)
数据元素的集合。在C语言中体现为结构体数组。
抽象数据类型 (ADT)
数学模型(struct)+ 操作(函数)。在C语言中体现在.h文件中的内容。
程序构成
程序 = 数据 + 算法(函数)
二、算法 (Algorithm)
1.定义
解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,每条指令表示一个或多个操作。
2.特征
-
输入输出特性 - 输入可选,输出必须
-
有穷性 - 执行步骤会自动结束,不能是死循环,每一步在可接受时间内完成
-
确定性 - 同一个输入得到唯一的输出
-
可行性 - 每一个步骤都是可以实现的
3.算法设计原则
正确性
-
语法正确
-
合法输入能得到合理结果
-
对非法输入能给出满足要求的规格说明
-
对精心选择的测试用例都能正常运行且结果正确
可读性
- 便于交流、阅读、理解
健壮性
- 输入非法数据时能进行相应处理,而不是产生异常
高效性
- 存储需求低,执行效率高
三、算法时间复杂度
1.定义
执行算法所花费时间的度量。
2.推导规则
-
用常数1取代运行时间中的所有加法常数
-
在修改后的运行函数中,只保留最高阶项
-
如果最高阶存在且不是1,则去除这个项相乘的常数
3.时间复杂度比较
O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(n³) < O(2ⁿ) < O(n!) < O(nⁿ)
示例
// O(n) 时间复杂度
for (int i = 0; i < 100; i++) {
sum = sum + i;
}
// O(1) 时间复杂度
sum = (n + 1) * n / 2;
四、线性表 (Linear List)
1.定义
零个或多个数据元素的有限序列。
2.内存特性
-
线性表的内存空间都在堆空间
-
数据元素本身可能包含多个属性,需要较大的内存
-
堆空间的生命周期由程序员控制(malloc/free)
3.抽象数据类型实现
通用数据类型定义
typedef struct person {
char name[32];
char sex;
int age;
int score;
} DATATYPE;
顺序表结构定义
typedef struct list {
DATATYPE *head; // 指向数据存储区
int tlen; // 总长度
int clen; // 当前长度
} SeqList;
4.基本操作接口
// 创建顺序表
SeqList *CreateSeqList(int len);
// 销毁顺序表
int DestroySeqList(SeqList *list);
// 遍历顺序表的所有数据
int ShowSeqList(SeqList *list);
// 添加数据(尾部插入)
int InsertTailSeqList(SeqList *list, DATATYPE data);
// 判断是否为满
int IsFullSeqList(SeqList *list);
// 判断是否为空
int IsEmptySeqList(SeqList *list);
// 按位置添加数据
int InsertPosSeqList(SeqList *list, DATATYPE data, int pos);
// 查找数据
int FindSeqList(SeqList *list, char *name);
// 修改数据
int ModifySeqList(SeqList *list, char *old, DATATYPE new);
// 删除一个数据
int DeleteSeqList(SeqList *list, char *name);
// 清空表
int ClearSeqList(SeqList *list);
五、关键要点总结
-
数据结构核心:高效存储和管理数据,支持基本操作
-
逻辑与物理结构:逻辑结构描述数据关系,物理结构实现存储方式
-
算法重要性:决定程序效率的关键因素
-
时间复杂度:衡量算法性能的重要指标
-
线性表基础:最简单且最常用的数据结构之一
-
ADT思想:将数据结构和操作封装,提高代码复用性和可维护性