你说的这种根据情况开辟空间的数组叫做动态数组,也就是
C 中的std::vector,在C中你可以自己实现,很简单,参考高票回答,也可以用现成的库,比如比较常用的GLib。
线性表的实现还有链表,相比动态数组的区别是,扩大空间时不需要拷贝,插入删除的复杂度为O
(1)(动态数组为O(n)),但占用空间较多,且不支持O
(1)随机访问。
不过不管怎么样,你需要什么样的数据结构,要根据你的需求来定。你应该把具体的问题描述出来,然后才能根据你的需要选择最合适的数据结构。如果你不需要O
(1)随机访问,但要保证O
(1)的插入删除性能,且多占用空间不是问题,那么链表就很适合你。如果随机访问或尽量减少空间占用很重要,但不需要O
(1)的插入删除操作,那就应该用动态数组。
当不知道长度时,你需要的数据结构,叫动态变长数组。下文简称为动态数组。也就是
C 中的std::vector。
其中,capacity表示容量,size表示实际有多少个数据。buf表示指向具体的内存。当capacity为4,size为3时,这时再放一个char,还够容量放。之后capacity和size都变为
4。
这时再需要放一个char,就已经放不下了。就需要重新分配一个更大的内存区间。并且将之前的数据复制到新空间,再释放掉旧的内存空间。通常的策略是将容量翻倍,从4扩大成
8。
这个分配新空间,复制数据,释放旧空间的过程,可以用函数realloc完成。假如在当前位置上还可以扩大容量,realloc就直接在原地扩大内存空间,避免了复制数据的开销。
将动态数组这个数据结构封装好。外面就不用再关心具体的内存分配过程了,可以一直往里面放数据。
而很多情况下,是可以估计到一个最终容量的粗略值的(不用太准确)。动态数组通常初始化时候,会有一个叫初始容量值的参数。这样传进去一个估计值,可以大大减少它重新分配空间的次数。
动态数组可算是最简单,又最常用的数据结构了。它可以保证内存的连续性,假如你放的数据不用连续,并且常常从中间插入和删除,你就需要链表了。