什么是顺序表
我们顺序表的底层是数组,是连续存放到数据,顺序表在物理结构上连续,在逻辑结构上一定是连续的。
顺序表属于线性表的一种,线性表就是相当于把一堆数据联系起来,从而达到一个理想的状态。
可以相当于我们平时生活中带的手串,本来毫不相干的两颗形状大小不一的装饰品打个孔用线或者皮筋串联起来,那么他们之间就构成了一种联系。
顺序表的分类
我们的顺序表的分类分为两类,分别是静态和动态。
静态顺序表
我们说过顺序表的底层是数组,那么我们的静态顺序表则是我们定长的数组。
静态顺序表定义:
struct SeqList
{
int arr[100];
int size;
};
结构体的中定了一个数组,给定了他的元素为100个,这就是一个定长数组。
因为这篇空间我可能不会用完,所以我们的size就是用来记录当前顺序表中的有效数据个数,当我们在我们arr数组中插入了一个数据,那么我们的size就为1,以此类推。
这样一个静态顺序表就定义好了。
动态顺序表
顾名思义,动态数据表就是动态内存开辟,确定了大小后去动态申请内存。
动态顺序表定义:
struct SeqList
{
int* arr;
int size;
int capacity;
}
首先我们动态并不清楚我们要存放多少个数据,所以我们给定一个指针类型的数组,然后我们还要知道他的有效个数,即我在数组中存放的数据个数。
当然我们手动开辟的空间也可能不会一下用完,所以用size用来记录当前数据的有效个数,假如我手动开辟了一个空间,我给他里面存了1,2,3,4,5,这五个数据,那么size就自然而然地等于5了。
那我们动态开辟空间肯定是一直慢慢的扩大的,当我们一开始开辟了10个整型类型空间,之后不够存放了,我们就继续动态开辟内存,那么用什么来记录我们当时已经开辟好的空间呢?所以我们需要定义一个变量用来记录这片空间的大小。
现在我们一个动态顺序表就定义完成了。
顺序表的选择
静态顺序表:
首先我们已知静态顺序表有一种特点就是定长数组,这个定长数组我们得给多少空间呢?答案是不知道,不可能提前知道需求。
假设某家公司新推出一款手游,我们现在想要玩游戏是需要实名的,假设游戏公司设定的玩家实名数量只有5万个储存的空间,随着用户使用越来越多,如果原来的储存量很少的话,一定会造成内存不够,那么当大于5万个用户使用的时候,可能会发现储存不进去,本可以储存20万个用户的数据却只存储了5万个,这样就造成了用户数据丢失的情况。
所以我们在使用静态顺序表时就会面临一个问题,就是空间给大浪费,给小不够。
动态顺序表:
通过和静态顺序表的一个对比,就是动态顺序表有着一个可以增容的特性,就是我用多少就开辟多少的空间,从而完美的避免了静态顺序表的一个问题。
举个例子:当我现在存储了10个数据,当我存储到第11个的时候发现空间不够了,那么就会先去申请200空间,这种情况我们就不会出现空间给大过多浪费和给小用户数据丢失的问题了,然后再进行下一步的操作。
所以我个人更推荐动态顺序表,因为灵活,对空间有很好的把控。
申请空间
要申请多大的空间 / 一次性增容多大的空间?
增容通常是成倍数增加的,一般是2倍或者3倍。
按照平时所说的,每次需要多少就申请多少确实是这个道理,但是若要频繁增这种情况就会造成性能低下的问题。
z这实际上是数学中《概率论》推论出来的,这边感兴趣的朋友可以去看看《概率论》。