大话数据结构 三(线性表)

接下来几篇内容将会介绍一些数据结构,可能结合算法对它们的特性进行说明,同时可以对算法的运行过程有一个初步了解。

线性表就是若干元素的有限序列,
有序的序列
线性表的抽象数据类型

线性表的存储结构

顺序存储结构

在这里插入图片描述
用一段地址连续的存储单元依次存储数据元素,包含起始位置、最大存储容量、当前存储数据个数
顺序存储结构包含的方法:

  1. 获取:将对应下标位置的元素返回
  2. 插入:将后续元素依次右移,插入对应的位置i
  3. 删除:删除i位置的元素,后面的元素依次前移一位,表长减一
    可以发现,线性表读数据的时间复杂度是O(1),插入删除则是O(n),适用于存取较多,而插入、删除少的场景(这里的存指的是直接在线性表末尾添加元素,而不是在某位置插入)。这也是日常编程使用的很多的一种数据结构

链式存储结构

在这里插入图片描述
用一组任意的存储单元存储数据元素,存储单元可以连续也可以不连续
可以想象,每个数据元素除了存储本身的信息以外,还需要存储一个指向其后继元素的信息。把这个信息叫做指针域,指针域中存储的信息叫做指针,而存储数据部分称为数据域。这两部分信息组成结点
在这里插入图片描述

单链表

每个结点只包含一个指针域

静态链表

用数组描述的链表
在这里插入图片描述
这种结构是使用了一系列连续的内存空间,但是每个元素不仅仅存储数据,还存储cur游标,它存储后继元素的下标,如上图,下标1位置的元素cur为2,表示它的下一个元素在位置2处。第一个元素存储的是备用链表的第一个元素的下标,备用链表就是指当前数组中未被使用的元素的集合,可以理解为空元素数组。最后一个元素相当于头结点,存储第一个插入元素的下标,上图是0
显然这种结构结合了数组和链表的特点,如果需要新增元素:
在这里插入图片描述
依次新增甲乙丁等元素,比如需要在乙和丁之间插入元素丙,那么首先通过第一个元素获取到当前备用链表第一个空闲元素7,将元素丙存入,然后将前一个元素(即乙)的cur指向丙的下标(即7),再将丙的cur指向下一个元素丁(即3),如下图:
在这里插入图片描述
可以看到,通过这种数据、游标分离的方式,虽然使用的仍然是地址连续的内存,但插入元素时不需要像顺序表一样频繁移动元素,同理删除元素,需要将删除的元素放入备用链表,即将其cur存储为第一个元素的cur(即当前备用链表的第一个元素),然后将第一个元素的cur存储为删除元素的下标,表示它成为了备用链表的第一个元素,那么备用链表的维护就完成了。
在这里插入图片描述
当然,这种存储结构虽然有效避免了插入删除元素的频繁移动操作,但是它需要在创建时指定数组长度,表长不确定的问题没有解决。并且失去了顺序存储存储结构随机存取的特性(顺序存储结构由于地址连续且元素位置连续,可以通过首地址+偏移获取到某个元素,而链表则需要遍历)

循环链表

将单链表尾结点指向头结点而形成的结构
在这里插入图片描述
当然,也可以使用尾指针,这样获取尾结点更方便
在这里插入图片描述
循环链表解决的问题是,需要从某个结点开始,遍历链表的全部结点。使用传统的单链表会比较麻烦

双向链表

可以发现,即使是循环链表,如果需要获取某个元素的前一个元素,非常麻烦,因此有了双向链表的结构,对于单链表的结点,加一个指向其前驱结点的指针:
在这里插入图片描述
当然,它的插入删除元素需要变更的指针就比较复杂一点,这里不深入学习代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值