一、什么是顺序表
顺序表,顾名思义就是连续存放一定数量的指定类型的数据。铁铁们,看到这里是否想到之前学习的某些知识和顺序表类似——数组。
数组是连续存放一定数量的指定数据类型的空间集合,而顺序表的底层就是数组,通讯录就是通过顺序表得以应用的(通讯录会在下一章讲到)。
顺序表的实现会使用到数组,指针,结构体以及动态内存管理相关的知识(不熟悉的铁铁们需要加油啦!)。
下来我们主要通过C语言来实现顺序表。
二、顺序表的初始化
先提前创建一个结构体变量SL sl(在后面测试和传参会用到)。
顺序表分为两种:静态顺序表和动态顺序表。
静态顺序表:
顾名思义就是安静的,不会动的顺序表。用专业的术语来说是定长的数组。直接给定定长的数组确实更方便,但我们仔细想一想这样初始化有没有什么问题呢?答案是有的,因为你不知道一下给定多少空间并且一旦给定就无法修改,给少了空间不够,给多了会造成空间浪费。因此在大多数情况下我们会使用另一种顺序表——动态顺序表。下面我们来介绍动态顺序表。
动态顺序表:
顾名思义就是可以改变长度的顺序表。通过改变数组存储空间的大小来改变顺序表的有效空间。而顺序表的初始化需要指定三个变量:数组(arr),有效数据个数(size),空间容量(capacity)。
给顺序表起个名字——SeqList(Seqence List)
我们这里通过typedef重新定义int类型和结构体变量(方便后续使用以及更改)。新定义的类型叫做SLDataList,结构体叫做SL。通过重命名类型我们可以将顺序表应用于多种数据类型(不用通过一个个更改类型)。
三、顺序表的销毁
既然有指针的初始化那么就有销毁,否则容易成为野指针。参考文件和野指针的处理,这里不再做过多解释。
四、顺序表功能的实现
我们需要顺序表实现对数据的增加,删除,查找,修改(增删查改)。进而为通讯录的实现做铺垫。
(1)尾插
实际插入数据我们需要判断,所传指针的有效性,空间容量是否为空以及空间容量和有效数据个数的关系(size<capacity)。为此我们创建一个空间申请函数SLCheckCapacity()。提前申请空间容量赋给一个新变量newcapacity(后面会用到),用realloc函数申请2--3倍的空间容量赋给临时的指针(防止指针所指空间为空)。判断指针后再将新的空间容量和新的指针地址赋给原变量。这样保证了代码的健壮性。接下来才是真正的尾插,直接将x(所插入的数据)放置到下标为size位置,请记住size要++,不然会导致数据丢失。
(2)头插
和尾插类似同样需要空间开辟。创建i变量,通过循环唯一区别的是将下标为i-1的值赋给下标为i+1的值(从后向前否则会导致数据覆盖丢失)。别忘了size++。
(3)尾删
这里尾删十分简单,直接size--即可。但需注意的是因为size要--,所以有可能减到0。故应用assert判断指针有效性。
(4)头删
同样要判断size--后指向的有效性。将i+1位置的数据赋给i后size--。
补充:--size和size--是一样的。
(5)指定位置插入/删除数据
插入:设置pos表示插入下标,从后向前将i-1位置的值赋给i(和头插类似)。
删除:将i+1位置的值赋给i(和头删类似)。记住size--。
(6)查找
这里的代码对各位铁铁很简单,唯一需要注意的是return -1的位置。不敢写到for循环体的内部(别问我怎么知道的)。补充:我这里注释是因为顺序表和通讯录写到一起了,各位贴贴不用哦。
到此为止我们顺序表实现的功能就全部完成了,想打印顺序表查看的可自行写代码查看(相信各位有这个能力)。
PS:各个实现函数名和参数在上述已经截图上传。
五、完整代码
SeqList.h
SeqList.c
test.c(测试函数各位自行解决)
恭喜各位坚持看完,若本篇有误请各位多多指教。
创作不易拜托各位铁铁多多评论和关注啦。