数据结构与算法 | 7-顺序表

本文介绍了顺序表,它是线性表的一种实现模型,将元素顺序存于连续存储区。阐述了顺序表基本形式,包括元素内置和外置顺序表,还说明了其结构由表头信息和数据区组成,实现方式有一体式和分离式,分离式更优,同时提及了存储区扩容策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 前言

在之前的一期博客中提到过线性表,具体见:数据结构与算法 | 6-线性表 ,里面提到线性表的概念为:
在这里插入图片描述
那本期要提到的顺序表和线性表有什么关系呢?

实际上,根据线性表的实际存储方式,分为两种实现模型:

  • 顺序表。将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
  • 链表。将元素存放在通过链接构造起来的一系列存储块中

2 什么是顺序表

2.1 顺序表的基本形式

根据元素的位置,顺序表的基本形式可以分为下面两种:

  • 元素内置顺序表
  • 元素外置顺序表

2.1.1 基本知识补充

  • 整数占4个字节,即4个存储单元

  • 字符占1个字节,即1个存储单元

  • 1个字节是8位,4个字节是32位,也就是有32个小格子来存储数据,具体见下图:
    在这里插入图片描述
    上图这32个小格子(4*8)就代表了整数1在内存中的存储方式。

  • 不论是整数还是字符,都属于变量的不同类型,那变量类型的本质是啥呢?

    • 一是变量类型决定了该变量占多少内存
    • 二是一开始存储该数据的时候就需要指定类型

2.1.2 元素内/外置顺序表

关于元素内/外置顺序表,具体见下图:
在这里插入图片描述

  • 左边图形表示元素内置的顺序表,右边则是外置。

想必大家肯定会问,为什么会有这两种顺序表的差异呢?本质原因就是顺序表里存储的数据的类型是否一致导致的!如果不一致,就会出现右边的元素外置情形,如果顺序表中数据类型都一样,就可以直接使用左边的形式。

不懂就问,那为什么顺序表中数据类型不一致就不能使用左边的形式呢?因为不同类型数据
存储占得字节不一样
,所以无法像左边一样按顺序来。

左边元素内置情况下:

数据查询时候的逻辑为:

  • 第一个元素Li[0] = 200,对应位置OX23,如果想要查询第3个元素,直接就是:

位置:OX23 + 3 * Byte4 = OX35 对应的元素12112,即 Li[3] = 12112

  • 上述公式中3表示偏移量。解释了为什么计算机从0开始计数,表示没有偏移量,i表示偏移量为i
  • Byte4表示相应数据类型所占字节数!本例中由于是整数,所以占4个字节!
  • 上述计算公式可以抽象为:
    在这里插入图片描述

右边元素外置情况下:

先考虑为什么这么存储!

上面也提到过,由于顺序表中数据的类型不一致,所以无法像左边直接按照位置元素内置进行存储(此时元素位置不连续),那怎么考虑呢?比较自然的想法就是:

  • 将此时顺序表中的元素的位置进行内置存储!即存储的不是元素,而是元素的位置了!
  • 然后再对元素的位置按照左边的方式进行存储,此时位置连续!

此时数据查询时候的逻辑为:

  • 第一个元素Li[0] = 12,对应位置OX324,内置存储的元素为OX100,而OX100对应的外置元素为12,查询完毕。
  • 如果想要查询第3个元素,直接就是:OX324 + 3 * Byte4 = OX336,而OX336的内置元素为OX110,其对应的外置元素为1000,即Li[3] = 1000,查询完毕。

2.2 顺序表的结构和实现方式

2.2.1 结构

关于顺序表的结构,上面我们看到了主要的部分,也就是数据是如何存储的,那顺序表中是不是只有存储的数据呢?答案很显然不是,具体的结构包括两部分:
在这里插入图片描述
表头信息+数据区!其中表头信息又包括两部分:

  • 容量。即顺序表最多能存储多少个数据
  • 元素个数。即顺序表现在已经存储了多少个数据了!

2.2.2 实现方式

什么叫实现方式?也就是表头信息和数据区如何组装在一起?是缠缠绵绵绕天涯还是分居两地?哈哈,分别对应的就是两种结构:

  • 一体式结构。即表头信息和数据区在一块存储区里。

  • 分离式结构。即顺序表中只存放表头信息,而数据放在独立的存储区中,通过顺序表中第三个位置信息,即链接实现和数据的关联。
    在这里插入图片描述
    那这两种实现方式哪一种更好呢?分离式结构!

  • 存储区替换时,分离式结构直接改变存储区以及顺序表中第三个位置的链接即可,而对于一体式结构则只能整体搬迁,即整个顺序表对象(指存储顺序表的结构信息的区域)改变了。

  • 存储区扩容时,分离式结构的表头信息不会发生变化,只需改变第三个位置的链接,即扩容后数据的首位置信息。而一体式结构需要改变所有的信息,无论是表头的还是数据区。
    在这里插入图片描述

注1:在Python的官方实现中,list就是一种采用分离式技术实现的动态顺序表。

上面提到存储区扩容,对于扩容,有着两种不同的扩容策略!

  • 策略1:固定数目扩容。
    • 优点:所需空间少
    • 缺点:如果频繁需要扩充而空间又每次不够的时候,需要消耗的时间成本较大。
  • 策略2:加倍扩容。【一般采用】
    • 优点:时间成本较少,一次到位。4→8→16→32…
    • 缺点:空间换时间。空间成本较高,但一般都会选择这么做,保证时间效率!

注2:在Python的官方实现中,list实现采用了如下的策略:
在建立空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入操作(insert或append)时,如果元素存储区满就换一块4倍大的存储区。但如果此时的表已经很大(目前的阀值为50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值