顺序表,是常用的一种数据结构,他的底层是连续的物理内存,所以他可以在O(1)的时间访问下标为N的位置,而且很多操作都是基于顺序表才可以操作的,例如:排序
所以顺序表是很重要的,他和链表各有优点,正因为他的底层是连续的物理空间,所以他并不适合头插和头删,以及中间插入删除等
下面我们就来看一下顺序表如何实现
首先我们来看一下,顺序表的结构
我们定义一个顺序表,该顺序表有一个DataType类型的一个指针,我们可以给这个指针后面开辟一段连续的空间,用这段空间来存储数据,里面的size是用来记录当前顺序表中有多少个元素,而capacity是用来记录当前顺序表的最大存储容量。
我们把该结构体typedef一下,可以给他重命名,叫做SL
下面我们看一下后面需要实现的,关于顺序表的函数
其中有初始化,销毁,尾插,头插,尾删,头删,还有随机插入,随机删除,还有打印顺序表,和查找函数
下面我们看一下第一个,初始化函数
下面我们看一下,初始化函数,初始化函数里面只需要把该变量中的指针a先开辟一小段空间,所以我们需要决定,刚开始有多少空间,然后我们把size初始化为0,我们在把capacity初始化为,刚开始可以最大存入数据的个数,我们把刚开始最大存入数据的个数初始化为4即可
既然有初始化,而且里面的内存是我们malloc主动开辟的,所以最后我们一定需要释放掉开辟的空间,所以我们需要一个销毁函数
而销毁函数很简单,我们只需要把变量中的a指针指向的那一段空间释放掉即可,同时把capacity和size设置为0即可
下面我们看一下尾插
我们先看一下尾插,尾插 ,既然是插入,那么我们当然得先检查一下容量是否足够,如果足够的话我们直接插入即可,如果不够的话我们就需要扩容之后再插入进去,所以我们需要一个检查容量的函数,等检查之后再插入即可
所以我们看一下如何检查容量,如果容量足够怎么办?如果容量不够怎么办?以及如果不够的话怎么扩容?
我们首先进去,检查size是否和capacity相等,如果相等的话就说明已经满了,如果不想等的话,说明没有满,直接return就行,那么满了,我们就可以进行扩容,所以我们需要用到一个函数realloc该函数需要传入,想要扩容的指针,在传入想要扩容后的大小,他的返回值是该空间的起始位置,所以我们需要接收一下,判断是否为空,如果为空的话则失败,退出即可,如果成功的话把a重新赋值为tmp变量,然后再把capacity重新设置为扩容后的大小。
等扩容后,我们就可以直接插入就可以了,所以我们看一下插入
尾插,我们直接在size那个位置插入,然后再让size+1 就可以了
下面我们看一下尾删
其实尾删特别简单,我们并不需要把最后一个数字设置为0在删除,我们顺序表中查看有多少数据,并不是看里面的元素,我们用的是size,有多少个size,我们就认为有多少个数据,所以我们只需要让size-1就可以了了
下面我们看一下打印函数
我们在顺序表中看有多少数据需要用到的是size,所以我们只需要打印size个数据就可以了,这样我们就可以使用一个循环打印就可以了
下面我们看一下头插
头插其实也并不难,我们先想一下,如果我们需要在前面插入一个数据,那么我们需要怎么做?
首先我们需要看一下,我们如何插入,既然是头插,那么我们当然是要让刚开始的位置有一个空余的位置,所以现在我们需要将顺序表中的数据都向后移动一个
就像这样,我们就可以把他空出来一个位置,然后插入进去就可以了
下面我们看一下头删
如果我们需要删除第一个数据,那么我们并不需要真正的删除,我们只需要让他覆盖就可以了,我们可以把第二个放在第一个把第三个放在第二个,把第n个放在n-1个位置即可
所以我们来看一下
就这样我们一个一个移动
就像这样,我们最后会变成这样,我们只需要让size在减1就可以了
我们在看一下随机插入删除
随机删除,就是传入要删除的位置,然后也是像头删一样覆盖就可以了,只不过这一次的位置不是覆盖第一个位置,而是覆盖到要删除的位置
随机插入也是相同的,所以我们只需要把想要插入的位置空开就可以了,像头插一样
最后我们来看一下find
我们查找只需要一个一个查找就可以了,如果相同的话则返回该位置数组的下标,如果没有的话就返回-1就可以了
这个就是今天的顺序表