0. 线性结构
数据结构中最常用最简单的结构是线性结构。
线性结构,又称线性表。逻辑结构上数据元素之间存在一个对一个的相邻关系。线性结构是n个数据元素的有序(次序)集合,它有下列几个特征:
1.集合中必存在唯一的一个"第一个元素";
2.集合中必存在唯一的一个"最后的元素";
3.除最后元素之外,其它数据元素均有唯一的"后继";
4.除第一元素之外,其它数据元素均有唯一的"前驱"。
1. 顺序表是什么?
顺序表是用一组地址连续的存储单元依次存储线性表中的各个元素,使线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中。
数组的缺点:大小(元素个数)不能改变,不能适用元素个数变化的情况。
数组可以看作无法改变大小的顺序表。
2. 顺序表怎么用?
顺序表通过一个结构体和结构体对应的接口使用。
3. 顺序表怎么实现?
3.1 定义结构
typedef int SeqType; //存储单元类型
typedef struct{
SeqType *elem; //存储空间基地址
int size; //当前长度
} List;
定义一个存储单元类型SeqType
是为了使顺序表适和更多数据类型,使用的时候修改SeqType
类型即可。
3.2 定义操作
- 初始化顺序表
为什么要初始化?因为局部变量默认初始化为随机值。
怎么初始化?把结构体变量成员赋值为合法的初始值。
bool sqlist_init(SqList* plist);
- 添加元素
int sqlist_append(SqList* plist,SeqType value);
int sqlist_prepend(SqList* plist,SeqType value);
- 获取元素
SeqType sqlist_get(SqList* plist,int index);
- 获取元素个数
int sqlist_size(SqList* plist);
为什么不直接从结构体获取?
- 插入元素
int sqlist_insert(SqList* plist,int index,SeqType value);
- 删除元素
SeqType sqlist_remove(SqList* plist,int index);
- 销毁顺序表
bool sqlist_destroy(SqList* plist);
4. 优化
- 容量
每次增加一个元素,都要重复释放申请内存。可以预先申请一部分备用。
int capacity; //当前分配的存储容量
每次预先申请多少?
- 创建
用户使用SeqType
忘记初始化,可以把结构体定义和初始化合二为一。
SeqType sqlist_create(int size);
- 随机访问元素
获取元素sqlist_get()
,只能获取到顺序表中的元素的副本,如果需要改变顺序表中的元素,可以提供如下函数。
SeqType* sqlist_at(SqList* plist,int index);
- 遍历
提供一个对顺序表的整体操作的接口。
typedef void (*SqList_Traversal)(const SeqType* value);
void sqlist_traverse(SqList* plist,SqList_Traversal fp);
5. 练习
- 实现一个清空接口
- 实现一个判空接口
- 实现一个查找指定元素的接口,返回元素下标
- 实现一个查找指定元素的接口,返回元素地址
- 实现比较两个元素的接口
- 实现交换两个元素的接口