什么是数据结构
数据结构是由数据和结构两个词结合而来,
那么数据由是什么
就比如我们日常生活中的1,2,3,4,5,a,b,c,d,e文字信息图片等,这些就是数据
那么结构又是什么?
想像一下如果我们有大量数据要管理,举一个例子就像我们计算机电脑硬盘里面的东西,如果我们在硬盘里面对于那些文件随便防止任何类型的文件都放在一堆,如果我们要想找某一个文件那将会非常困难,可读性非常差。
如果我们把他们提前整理好,同类型的文件放在一起,形成一个结构这样查找起来就方便多了。
数据结构是计算机存储,组织数据的方式
什么是顺序表
顺序表是一种数据结构它使用计算机内存中的一组地址连续的存储单元来存储线性表的元素。这种存储方式使得线性表中逻辑上相邻的数据元素在物理存储位置上也相邻,通过这种方式,顺序表可以高效地执行插入、删除、查找等操作。顺序表的主要优点包括动态分配空间、支持随机访问元素,以及逻辑顺序与物理顺序的一致性。顺序表可以分为静态和动态两种形式,静态顺序表适用于元素数量固定的情形,而动态顺序表的大小可以根据需要调整。
根据上面的内容我们了解到顺序表是一种数据结构,在计算机内存一组连续的地址可以用来存放东西,提到内存中连续的地址,我们就很容易想到一个东西,叫数组,其实顺序表的底层逻辑就是数组,只是对数组进行了封装,实现了常用的查增删改等接口。
顺序表的分类
顺序表分为静态顺序表和动态顺序表
静态顺序表
顾名思义静态顺序表是静态的,大小是不可改变的,像这张图片
动态顺序表
顾名思义动态顺序表是动态的大小是可以改变的,像这张图片
根据这两个顺序表的对比,我们可以对比出他们谁好谁坏,可以很明显的看到动态顺序表要明显优于静态顺序表动态顺序表的一个很明显的优势是可以动态增容,而静态顺序表不能,想象一下如果我们要存放数据,使用静态顺序表那么一次性必须申请非常大的空间才能防止空间不够用,而动态顺序表就不用,他可以根据需要数据的大小随意调整,这里我们主要讲动态顺序表。
动态顺序表的C语言实现
如果我们要创建一个顺序表,我们首先想到的就是创建一个结构体用来存放动态顺序表里面的一些信息,像可以空间大小,或者实际使用空间,下面是代码
typedef int Data_type
struct seqlist
{
Data_type* arr;//数组地址
int size;//实际使用空间
int memespace//总空间大小
};
typedef struct seqlist sl;//重定义方便书写代码
这里我们创建了一个结构体用来存放整形数据的顺序表相关信息,又重定义了一下,这样有助于我们书写代码。
现在我们来说一下具体思路
具体思路
我们创建了一个int size和int memespace来维护我们的arr数组顺序表
在他们的基础之上我们来实现增删查改功能,在写完一个功能的时候在测试一下这就是思路。
初始化
首先我们先来看看初始化
void Initseqlist(sl*ps)
{
ps->arr = NULL;
ps->size = 0;
ps->memespace = 0;
}
这里我们用了一个指针来接收seqlist结构体,为什么要采用地址传递,那是因为这样可以减少内存的占用将结构体的指针作为参数传递给函数,这样函数内部的操作是指向原始结构体的指针,可以直接修改结构体总的来说就是地址传递可以修改原始指针指向的值,而非地址传递不能修改原始指针指向的值这里我们把顺序表数组和实际使用空间,和总共大小空间都初始化了一下赋值为0和空指针NULL,同样也可以在初始化的时候也可以分配内存大小空间,像这样
(int*)malloc(2*sizeof(Data_type));//申请了两个大小为int的空间就
我们来看看主函数
我们后续的测试功能全在这个主函数里面;
int main()
{
sl SL;//通过结构体创建了一个名为SL的变量,前面定义过的
Initseqlist(&SL);//初始化这个SL变量
return 0;
}
申请空间
下面是代码
void cheakmemory(sl* ps)
{
if(ps->memespace == ps->size)
{
int new_memespace = ps->memespace == 0?4;2*ps->memespace;
Data_type*temp = (Data_type*)realloc(ps->arr,new_memespace*sizeof(Data_type));
if(temp == NULL)
{
perror("realloc");
printf("申请空间失败\n");
}
ps->memespace = new_memepace;
ps->arr = temp;
}
这里我们首先用了个if来判断是否需要新增空间如果实际使用空间和总共大小空间相等的话就代表空间满了需要申请空间,就进入if语句
int new_memespace = ps->memespace == 0?4;2*ps->memespace;
这段代码的意思是如果总共大小空间等于0的话就预备申请4个空间如果不等于0就预备申请原来大小的两倍空间,为什么要申请两倍的空间呢,那是一个数学问题,在数学中得到如果大小不够申请原来的两到三倍空间是最合理的,就像手机存储一样最开始8g到16g到现在的128,256g都是成倍提升的。为什么这里是预备申请,是因为在下一行代码
Data_type*temp = (Data_type*)realloc(ps->arr,new_memespace*sizeof(Data_type));
这里才是在实际申请空间,这里用了realloc函数来申请空间如果不知道realloc内存函数怎么用详见这篇文章
动态内存管理
这里的判断都是和realloc函数相关的,这里就不过多说明了
if(temp == NULL)
{
perror("realloc");
printf("申请空间失败\n");
}
ps->memespace = new_memepace;
ps->arr = temp;
}
<