目录
一、数据结构
1.1 数据结构是什么
1.2 为什么需要数据结构
最基础的数据结构:数组。
1.3 有了数组,为什么还要学习其他的数据结构?
二、顺序表的概念及结构
2.1 线性表
2.2 顺序表分类
2.2.1顺序表和数组的区别
2.2.2顺序表分类
struct Seqlist
{
int arr[100];
int size;
};//这是静态顺序表,局限性很大,空间给小了不够,给多了浪费
动态顺序表
struct Seqlist
{
qen* arr;//因为是动态申请,所以这里就不用数组形式,用指针形式
int size;//有效数据个数
int space;//申请的空间容量
};//这是动态表,比较灵活
三、动态顺序表的实现
3.1表的初始化
#include"4_13.h"
void testslin()
{
struct Seqlist s;
Slin(&s);
}
int main()
{
testslin();
return 0;//打断点进行测试
}//测试顺序表初始化与销毁函数
这边调试可以发现并没有出错。
3.2表的销毁
因为动态表涉及到动态内存开辟,所以要记得free
void SlDestory(struct Seqlist* p)
{
assert(p);
free(p->arr);
p->arr = NULL;
}
接下来进行顺序表的增(即在原数据表中插入数据)
3.3增
这里首先来说说首插与尾插
在这之前,我们先将表中存储的数据类型进行重命名为qen(qenre)
typedef int qen;
因为在表中存放数据的时候,不可能只存放一种类型的数据,如果不进行重命名,到存放其他类型
的数据的时候改起来就很麻烦,这里直接使用typedef进行重命名,到时候修改的时候把数据只用
改这里一处就可以了
3.3.1尾插
尾插,即从顺序表的末尾进行数据插入。
定义变量x为想插入的数据
这里由于是直接插入数组的尾部,所以不需要向首插那样考虑数据覆盖的情况。
这里发现,当前顺序表中有效数据个数size正好就是插入数据时的数组下标
那么在成功插入一个数据后,该表中有效数据增加,则需要一个size++
if (p->size == p->space)//判断是否需要扩容p->arr的空间
{
p->arr = realloc(p->arr, sizeof(qen) * sizeof(p->arr) * 2);
}//直接这样写可以吗
这样写可能会造成数据丢失
因为realloc函数可能会开辟失败,返回NULL,这样写的话不仅开辟不成功 ,原来放在表中的数
据也丢失了,那就寄了。
那就再搞个指针来接收他,看他是不是NULL,不是NULL再赋值给p->arr
void Slinsertback(struct Seqlist* p, qen num)
{
assert(p);
if (p->size == p->space)//判断是否需要扩容p->arr的空间
{
//p->arr = realloc(p->arr, sizeof(qen) * sizeof(p->arr) * 2);这样写不行
//因为realloc函数可能会开辟失败,返回NULL,这样写的话不仅开辟不成功
//原来的数据也丢失了,那就再搞个指针来接收他,看他是不是NULL,不是NULL再赋值给p->arr
qen* judge = realloc(p->arr, (sizeof(qen)) * p->space * 2);
p->space = newspace;//这里记得要把表的总空间进行赋值
if (judge == NULL)
{
perror("");
return;
}
else
p->arr = judge;
}
p->arr[p->size++] = num;//插入在表的末尾,插入成功后表的有效数据+1
}
将扩容操作直接写成个函数
void newspacecheck(struct Seqlist* p)
{
if (p->size == p->space)//判断是否需要扩容p->arr的空间
{
int newspace = p->space == 0 ? sizeof(qen) : 2 * p->space;
p->space = newspace;//这里记得要把表的总空间进行赋值
qen* judge = realloc(p->arr, sizeof(qen) * newspace);
//因为realloc函数可能会开辟失败,返回NULL,这样写的话不仅开辟不成功
//原来的数据也丢失了,那就再搞个指针来接收他,看他是不是NULL,不是NULL再赋值给p->arr
if (judge == NULL)
{
perror("realloc fali");
return;
}
else
p->arr = judge;
}
}
那么我们来测试一下
void testSlinsertback(struct Seqlist* p)
{
Slin(p);
Slinsertback(p, 1);
Slinsertback(p, 1);
Slinsertback(p, 1);
Slinsertback(p, 1);
Slinsertback(p, 1);
}
int main()
{
struct Seqlist s;
testSlinsertback(&s);
return 0;//打断点进行测试
}
在这里报了个错误,来看看是什么情况
可以发现这里space是0,所以在这里进行空间开辟的时候,还需要判断原空间是否是0
如果判断是0,重新定义一个变量newspace ,那么这里就默认给newspace开辟qen类型大小的一
个空间,再将代码修改一下
void Slinsertback(struct Seqlist* p, qen num)
{
assert