数据结构初阶——顺序表

前言

时隔几月,终于又更新博客了。在这几个月期间,笔者已经学完了C语言的基础语法,目前正在学习数据结构的初阶,由于之前的内容缺的太多,笔者就直接写数据结构的博客了。

数据结构

既然要学习数据结构,那我们得先知道数据结构是什么。简单点来说,数据结构就是计算机存储,组织数据的方式。为了将数据进行一个有效的存储和管理,我们就得使用数据结构,这就是学习数据结构的原因之一。

线性表

线性表是一种数据结构的统称,其包含链表、顺序表等结构,而这些结构有相同之处就是n个具有相同特性的数据元素的有限序列,在逻辑结构上,是线性排列的,但是在物理结构上就不一定了。

至于物理结构和逻辑结构有什么区别,我到时候会根据结构的不同进行介绍。

这篇博客的主要目的就是介绍线性表的一种——顺序表

顺序表的介绍

顺序表,顾名思义,是按照顺序来排列的一种结构。该结构在逻辑结构和物理结构上都是连续的。逻辑结构很容易理解,就是人为规定的连续结构,而物理结构则是数据的地址在内存中存储的结构,而顺序表就是一个物理地址连续的线性结构。

我们之前学习过数组,一个数组里的元素数据类型都是相同的,而每个相邻元素的地址都是连续的,很符合顺序表的条件,因此,我们认为,数组就是顺序表的底层结构,代码的实现就是在数组的基础上进行的。

静态顺序表和动态顺序表

顺序表分为静态顺序表和动态顺序表。这两者的区别在于空间大小是否可以改变。

由于顺序表是在数组的基础上实现,那么在定义静态顺序表时,会给定一定的空间,之后空间大小就不能再进行改变。反之,动态顺序表会根据需要来进行一定的扩容处理。

相较于静态顺序表,我们更多用的还是动态顺序表。

那么接下来就是对动态顺序表的代码实现。

顺序表的代码实现

顺序表的代码的行数比之前学习语法时的行数要多得多,所以我们得慢慢解读讲解。

准备工作

我们先得创建两个源文件和一个头文件

在SeqList.h头文件中

我们定义了一个顺序表的数据类型和结构体,此结构体存储了顺序表的重要信息,那么接下来就是顺序表的接口实现

顺序表的接口实现

想要在顺序表当中存储数据,就得封装很多函数来对顺序表进行增删查改这些操作,最基本的,先要对顺序表进行初始化,而使用完顺序表后需要进行销毁,实现如图

下图是在SeqList.c文件中实现的

至此,我们完成了初始化和销毁函数的封装,接下来,就要对数据进行操作了

数据的操作

在对顺序表的数据进行增删时,有不同的方法。由于顺序表是按照顺序进行存储的,所以插入数据时,可以从头部、尾部或者指定位置插入,删除也是一样,分为头删,尾删和指定位置删除,接下来我们一一进行讲解、代码的实现

在插入数据之前,我们得先检查顺序表的空间是否足够,如果不够的话得进行扩容。一般情况下是进行双倍扩容。所以,我们需要额外封装一个函数来检查容量

在这段代码中,我们先判断psl中的size是否等于capacity,若两者相等,则证明此时顺序表的空间已经用完或者是还没有数据,则需要开辟空间。在定义新的空间大小时又使用了三目操作符“?:”来判断空间是否为空,以此来赋予空间,紧接着就是使用realloc动态内存管理的函数来开辟一定的空间,再判断开辟空间的成功与否,这样,就可以对顺序表进行操作了。

首先先完成的是尾插函数的封装,如图

尾插操作较为简单,关键点在于我们得清楚psl->size作为数组下标使用时指向的是最后一个数据的下一个位置,这样,我们就能直接在psl->a[psl->size]位置直接插入x数据,记住,插入后有效数据的个数就得加一。

接下来是头插操作,较尾插稍复杂

较尾插操作,头插需要将所有数据都先向后移一格,这就要用到一个循环将数据后移,然后再将数据插入到下标为0的位置,这就是头插。

还有一个插入操作就是在指定位置插入,这时候函数就得多传一个数据,就是需要插入的位置,传的是数组下标,代码实现则是

对代码进行讲解,我们首先得判断,传过来的pos是否是在顺序表有效数据之内,若不在该范围之内,则断言报错。程序继续进行,我们要进行的操作与头插类似,需要将pos位置之后的数据向后移一个位置,然后再在pos位置插入数据,一个循环就能解决,当然,不要忘了size需要加一。

接下来就是删除操作了,我们需要注意的是,删除操作不需要将数据赋予一个特定的值,只需让有效数据的个数减一,或者将数据整体移动就行了,具体看代码实现。

首先是尾删操作

在这里,我们添加了一条断言语句,来判定顺序表的有效数据个数,若大于零,则对有效数据直接进行--的操作,这样就完成了尾删。

接下来是头删

头删操作,需要使用一个循环将所有数据向前移一个位置,以此来覆盖之前的数据,达到删除的效果。

指定位置删除的操作也是类似,代码如图

在这,我们也需要判断指定位置的大小是否在范围以内,与指定位置插入不同的是,pos的值不能等于size,因为在顺序表中size位置并没有数据,所以也不能进行删除。之后的操作与头删类似,通过一个循环实现。

满足上述接口,我们可以对顺序表进行插入删除了,首先得封装一个打印函数

之后再在主函数中实现接口

我们一次性将所有的接口都展示出来了,一目了然,这样就完成了顺序表的设置。

这是所有接口的声明,位于SeqList.h头文件当中。

结语

顺序表算是数据结构比较简单的一种结构了,但其代码的复杂程度远超之前学习的代码,可见,数据结构的学习是需要一个练习的过程,希望我们都能坚持下去。

The End

  • 35
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值