线性表(大话结构略读)

线性表定义

ddf

线性表的抽象数据类型

![[../../attach/Pasted image 20231010225948.png|800]]

![[../../attach/Pasted image 20231010230301.png|825]]

线性表的顺序储存结构

在这里插入图片描述

顺序储存表 插入元素

在这里插入图片描述

顺序储存表 删除元素

在这里插入图片描述在这里插入图片描述

顺序存储表 插入与删除时间复杂度总结

  1. 若元素要插入到最后一位,或者删除最后一个元素,此时时间复杂度为O(1),因为此时不需要移动元素
  2. 若元素要插入到第一位,或者删除第一个元素,此时时间复杂度为O(n),因为此时要移动所有元素向前或者向后
  3. 若是平均情况,将元素插入第i个位置,或者删除第i个元素,需要移动n-i个元素;根据概率原理,每个位置插入或者删除元素可能性相同.也就是说位置靠前,移动元素多;位置靠后,移动元素少.最终平均移动次数和最中间的那个元素的移动次数相等,为(n-1)/2

总结:线性表的顺序储存结构,在存、读数据时,不管哪个位置,时间复杂度都是O(1);而插入或删除时,时间复杂度都是O(n)。这就说明,它适合元素不太变化,而更多是存取数据的应用。

线性表顺序存储结构的优缺点

在这里插入图片描述

线性表的链式存储结构

在这里插入图片描述
单链表中,我们在C语言中用结构指针来描述.

在这里插入图片描述
上方的Node和Linklist分别是指结点和链表两个不同的概念,但是都是用该结构体的成员构成

链表结点之间的插入元素

在这里插入图片描述
在这里插入图片描述

注意插入元素的代码写法:是先对s->next=p->next,这是将结点s"链接"到后半段链表中,再讲p->next=s,是把前半段链表"链接"到结点s
如果两者反了,先对p->next=s,此时结点p->next直接变成了结点s,而s->next则变成了p->next->next在这里插入图片描述

链表结点之间的删除元素

在这里插入图片描述在这里插入图片描述

链表 创建整表

单链表是一种动态结构,对于每个链表来说,它所占空间大小与位置不需要预先分配划定,可以根据系统情况和实际需求即时生成。
所以创建链表的过程就是一个动态生成链表的过程。即从“空表”的初始状态起,依次建立各元素结点,并逐个插入链表。

头插法创建链表

这段算法代码中,我们使用插队的办法,始终让新结点在第一的位置,将此算法简称为头插法

在这里插入图片描述

尾插法创建链表

将新节点都放在最后,这是排队的正常思维,所谓的先来后到
在这里插入图片描述

在这里插入图片描述

循环结束后,应让此链表的指针域置空,因此有了"r->next=NULL",以便以后遍历时可以确认其是尾部

链表 整表删除

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

注意:有人觉得q的存在不必要,可以直接释放结点p,再p=p->next;可释放结点p后,p的指针域也消失了,就无法找到p的下一个结点

链表 读取

在单链表中,由于第i个元素的位置没办法一开始就知道,必须得从头开始找
在这里插入图片描述
在这里插入图片描述由于单链表的结构中未定义表长,所以不知道是先知道要循环多少次,因此也就不方便使用for来控制循环,其主要核心思想是**“工作指针后移”**

链表结构和顺序存储结构优缺点

在这里插入图片描述

  1. 若线性表需频繁查找,很少需要插入和删除操作时,宜使用顺序存储结构;若需要频繁插入和删除时,宜采用单链表结构.

如游戏开发中,用户注册的个人信息,除了注册时插入数据外,绝大多数是读取,可以考虑用顺序存储结构.而玩家的武器或者装备列表,可能会随时增加或者删除,此时就可以使用单链表

  1. 如果线性表中元素个数变化较大或者根本不知道有多大,最好用单链表结构,这样可以不考虑存储空间大小问题;而事先知道线性表的大致长度,顺序存储结构效率会很高

静态链表(静态链表详谈)

线性存储结构的一种,静态链表的数据全储存在数组中,但存储位置是随机的,数据的一对一关系是通过一个游标维持

在这里插入图片描述
静态链表存储结构如下
在这里插入图片描述
与链表一样,该结构体即是可以作为结点,也可以作为链表

静态链表 链表初始化

我们通常对数组的第一个和最后一个元素作为特殊元素处理,不存数据,我们通常把未被使用的数组元素成为备用链表。

数组第一个元素的cur用来存放备用链表的第一个结点的下标;最后一个元素的cur则存放第一个有数值的元素的下标,相当于单链表中头结点作用。
在这里插入图片描述

此时的图示如初始化的数组状态,代码如下:

在这里插入图片描述
该段代码的循环中是将数组游标进行串联

假设我们将数据已存入静态链表中,此时它将处于如下状态:
在这里插入图片描述

静态链表的插入

前面说过,动态链表的结点申请和释放,需要malloc函数和free函数;在静态链表中操作的是数组,我们需要自己实现这两个函数才可以做插入和删除的操作。

备用链表的串联

为了辨明数组中哪些分量未被使用。解决的方法是将所有未被使用过的和被删除的分量用游标连成一个备用的链表。每当进行插入时,并可从备用链表取得第一个节点,作为待插入的新结点。
在这里插入图片描述

在这里插入图片描述

插入元素

在这里插入图片描述

在这里插入图片描述
第11行~第12行的作用:k在利用游标与循环进行遍历,直到找到指向第i个元素的游标为止,并将值赋予k。

代码效果如下

在这里插入图片描述

静态链表的删除操作

删除在L中第i个数据元素e
在这里插入图片描述

在这里插入图片描述
先用循环找到删除元素的前驱,即为k;再j保存k的后继元素,即为删除元素;将删除元素的游标赋给k,这时删除元素已经交代好后事可以离开了

Free_SSL函数的作用
在这里插入图片描述将头元素游标赋值给删除元素的游标,使该空闲空间链接下一个空闲空间;删去元素的下标给头元素的游标,使头元素链接该空闲空间

在这里插入图片描述

查询数据元素个数

在这里插入图片描述

静态链表优缺点

在这里插入图片描述

循环链表

在这里插入图片描述
循环列表解决了一个很麻烦的问题,如何从当中一个结点出发,访问链表中所有结点.
在这里插入图片描述在这里插入图片描述
在单链表中,我们有了头结点时,我们可以用O(1)的时间访问第一个结点,但对于要访问到最后一个结点,却需要O(n)时间,因为我们需要将链表全扫描一遍

所以,我们创造了以下方法——创建一个尾指针:
在这里插入图片描述

链表合并

在这里插入图片描述在这里插入图片描述
图解步骤如下

在这里插入图片描述也是最后再修改rearB->next的值,否则第二步rearB->next->next的值会发生改变,导致rearA->next断链

双向链表

在这里插入图片描述
双向链表的存储结构如下:
在这里插入图片描述

双向链表的循环链表

在这里插入图片描述

双向链表的插入元素

在这里插入图片描述在这里插入图片描述

对赋值的理解(额外的想法)

在这里插入图片描述在这里插入图片描述

双向链表的删除

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值