一.对顺序表的理解:
顺序表其实就是基于数组来实现的。
其实顺序表是线性表的一种。
我们从两个方面(物理结构和逻辑结构)说明线性表和顺序表。
线性表是具有相同特性的数据结构的集合。其物理结构是不一定连续的,而其逻辑结构是连续的。
因为顺序表是基于数组实现,所以其物理结构是连续的,逻辑结构也是连续的。
1.顺序表的分类:
静态顺序表:
静态顺序表是基于定长数组来实现的,所以比较局限,无法扩大长度。而当你数组大小给大时会浪费空间,而当你给小时空间又不够用,所以一般都不用静态顺序表。
动态顺序表:
动态顺序表基于指针,这样在开辟空间时可以更加方便扩展空间大小,并且要记录当前空间容量。
二.动态顺序表的实现:
首先分装两个文件,Seqlist.c中写关于动态顺序表一系列操作的详细实现。Seqlist.h中写需要的头文件和操作函数的声明还有动态顺序表的初始化。
再分装一个test.c的文件用来对顺序表各种操作的测试。
1.动态顺序表的初始化:
将类型重命名当以后想改时更加方便且高效。
将结构体重命名让代码更加简单。
初始化顺序表:
在这里要用指针传参,传递顺序表的地址,这样才能访问到,并且修改与初始化。
2.动态顺序表的销毁:
3.动态顺序表空间检查和增容:
检查空间是否有足够插入数据的空间,若不够则增加内存空间。若足够就使用。
先判断顺序表中有效数据与当前空间是否相等,若相等则说明需要扩容新的空间
若相等现在就进行扩容:
扩容第一步先判断顺序表空间还有多少,若其等于0则先给4个空间不用翻倍扩容节省一定的空间,若其不等于0则需要翻倍扩容,一般翻倍扩容都是翻2倍(根据数学原理)。
当记录当前空间大小的扩容完毕后,开始真正扩容空间给顺序表中的动态数组利用realloc给其扩容:
这里要利用一个临时指针存放申请完空间的地址,因为不用的话如果申请失败会返回空指针,而直接用顺序表中的指针接受不仅没有开辟空间成功还将原本的数据给丢失了。
这就是整个函数的全部内容
4.动态顺序表尾插数据:
尾插之前要检查空间是否足够插入数据, 若不够正好一起开辟了空间.
图解分析如何进行尾插数据:
这里测试一下是否成功:
在销毁之前打一个断点,经过调试可以看出顺序表中存放了三个数据1,2,3,有效数据size也为3个,空间刚好开辟四个,所以目前为止是正确的。
5.动态顺序表头部插入数据:
跟尾插一样首先要检查空间是否足够,这里调用检查空间函数即可完成检查和增容
这里画一下图解,更好的写出代码:
这里测试一下,在尾插2和3后,头插一个1:
这是尾插2和3之后的监视图:
头插1之后:
头插成功,则头插函数的代码也就完成了。
6.动态顺序表的数据打印:
因为每次调试会太麻烦,所以写一个打印函数能更加的直观看到数据
也是成功完成打印顺序表函数
7.动态顺序表尾删数据:
尾部删除数据只需要将size(有效数据个数)减掉1即可,里面的内容当要尾插或头插时自己会被覆盖。
原本是1 2 3经过尾部删除函数后变成1 2 所以尾部删除数据函数也成功了。
8.动态顺序表的头删数据:
根据图解即可写出:
测试一下头部删除数据是否成功:
9.动态顺序表的查找数据:
测试一下是否能够成功找到:
10.动态顺序表删除指定位置数据:
图解如下:
根据图解可以写出代码:
这里测试一下是否能成功删除指定位置数据:
这里正好将下标为2的数据删除,所以测试成功
11.动态顺序表在指定位置插入数据:
如果这样想的话当在起始位置插入一个数据时会导致后面数据都会被覆盖掉导致数据丢失
所以从后往前覆盖时就不会出先这样的情况:
这样可以写出正确的代码:
再运行一下在头部插入一个0:
三.总结:
以上就是实现动态顺序表的所有功能,增删改查。
分别由三个文件实现,一个测试文件,一个顺序表的头文件,里面包含所有要用到的头文件,和要使用函数的声明,而顺序表的源文件任务就是实现函数,完成任务。
这就是顺序表实现的所有内容,谢谢观看。