🎉 前言:动态顺序表是C语言数据结构中的基础重点内容,相比静态顺序表,它能根据数据量动态调整存储空间,灵活性更高。本文将聚焦动态顺序表的核心操作——初始化、销毁、头部插入、尾部插入、头部删除、尾部删除,从原理分析到代码实现逐步拆解,适合刚入门数据结构的同学学习参考~
一、先搞懂:动态顺序表的结构定义 📚
动态顺序表的核心是通过指针指向动态开辟的数组,同时记录当前存储的数据个数(有效长度)和数组的最大容量,结构定义如下:
💡 说明:使用typedef重定义结构名和数据类型,后续使用和修改时更便捷,比如想存储char类型,只需修改SLDataType为char即可。
二、核心操作实现 🔧
2.1 初始化操作(SLInit)
初始化的目的是将顺序表的指针置空、有效长度和容量置0,避免野指针问题。
实现代码:
💡 注意:必须传入结构指针(SL* ps),如果直接传结构体变量,会进行值拷贝,修改的是拷贝后的变量,原顺序表不会发生变化。assert断言在Debug模式下生效,Release模式下会被忽略,用于调试时检测空指针。
2.2 销毁操作(SLDestroy)
动态顺序表的数组是通过malloc动态开辟的,使用完后必须手动释放,否则会造成内存泄漏。销毁操作的核心是释放动态开辟的空间,然后将指针、size、capacity重置。
实现代码:
💡 关键:free之后一定要将指针置空!如果不置空,ps->a会变成野指针,后续如果误操作该指针,会导致程序崩溃。
2.3 扩容操作(SLCheckCapacity)【辅助操作】
在进行插入操作前,需要先检查当前顺序表的容量是否足够。如果size == capacity,说明容量已满,需要进行扩容。这是动态顺序表的核心优势所在,扩容操作通常是开辟一块更大的空间(一般是原容量的2倍,效率更高),然后将原数据拷贝到新空间,最后释放原空间。
实现代码:
💡 说明:
-
realloc函数可以在原空间基础上扩容,如果原空间后面有足够的连续空间,会直接在原空间后追加;如果没有,会开辟新空间并将原数据拷贝过去,然后释放原空间。
-
初始容量设为4是经验值,避免初始容量过大造成空间浪费,也避免容量过小导致频繁扩容。
-
必须检查realloc的返回值,若开辟失败会返回NULL,直接赋值给ps->a会导致原空间地址丢失,造成内存泄漏。
2.4 尾部插入操作(SLPushBack)
尾部插入即在顺序表的最后一个有效数据后面添加新数据,步骤:先检查容量(调用SLCheckCapacity),然后将新数据存入size位置,最后size自增1。
实现代码:
📌 示例:若当前顺序表为 [1,2,3](size=3,capacity=4),尾部插入4后,顺序表变为 [1,2,3,4],size=4。
2.5 头部插入操作(SLPushFront)
头部插入即在顺序表的第一个位置添加新数据,步骤:先检查容量,然后将所有有效数据从后往前依次向后移动一位(避免覆盖数据),最后将新数据存入0位置,size自增1。
实现代码:
📌 示例:若当前顺序表为 [1,2,3](size=3),头部插入0后,先将3移到4位置、2移到3位置、1移到2位置,再将0存入0位置,顺序表变为 [0,1,2,3],size=4。
💡 注意:移动数据必须从后往前,若从前往后移动,会导致前面的数据覆盖后面的数据,造成数据丢失。
2.6 尾部删除操作(SLPopBack)
尾部删除即删除顺序表的最后一个有效数据,步骤:先检查顺序表是否为空(size>0),然后直接将size自减1即可(无需修改数据,后续插入会覆盖)。
实现代码:
/
💡 为什么不用手动修改最后一个数据?因为size是有效长度的标志,后续访问和插入都会以size为依据,原最后一个数据会被视为“无效数据”,不会被访问到,下次尾部插入时会直接覆盖。
2.7 头部删除操作(SLPopFront)
头部删除即删除顺序表的第一个数据,步骤:先检查顺序表是否为空,然后将所有有效数据从前往后依次向前移动一位(覆盖第一个数据),最后size自减1。
实现代码:
📌 示例:若当前顺序表为 [0,1,2,3](size=4),头部删除后,将1移到0位置、2移到1位置、3移到2位置,size=3,顺序表变为 [1,2,3]。
三、测试代码(验证功能) 🧪
为了验证上述操作的正确性,我们可以写一个main函数进行测试:
四、常见问题与注意事项 ⚠️
-
传入空指针:所有操作函数的参数都是SL* ps,必须传入结构体变量的地址(&sl),不能传入NULL,否则assert会触发报错。
-
空表删除:删除操作(SLPopBack、SLPopFront)前必须确保顺序表不为空(size>0),否则会触发断言报错,实际开发中也可以用if判断并返回错误信息。
-
扩容失败:realloc可能会开辟空间失败(返回NULL),必须检查返回值,否则会导致原空间地址丢失,造成内存泄漏。
-
数据移动方向:头部插入要从后往前移动数据,头部删除要从前往后移动数据,方向错误会导致数据覆盖丢失。
-
忘记销毁:动态顺序表使用完后必须调用SLDestroy释放空间,否则会造成内存泄漏,长期运行的程序会因此耗尽内存。
🎯 总结:动态顺序表的核心是“动态扩容”,围绕初始化、销毁、头尾增删的操作都依赖于size和capacity的管理。掌握这些基础操作后,后续学习中间插入、中间删除、查找等操作会更加轻松。建议大家动手敲一遍代码,结合测试案例理解每一步的原理,加深记忆~
#C语言 #数据结构 #动态顺序表 #顺序表核心操作 #程序员入门
14万+

被折叠的 条评论
为什么被折叠?



