Chapter2.2:线性表的顺序表示

news2024/11/15 12:00:17

该系列属于计算机基础系列中的《数据结构基础》子系列,参考书《数据结构考研复习指导》(王道论坛 组编),完整内容请阅读原书。



2.线性表的顺序表示

2.1 顺序表的定义
  • 线性表的顺序存储亦称为顺序表,是用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的两个元素在物理位置上也相邻;

  • 1 1 1个元素存储在线性表的起始位置,第 i i i个元素的存储位置后面紧接存储的是第 i + 1 i+1 i+1个元素,称 i i i为元素 a i a_i ai在线性表中的位序;

  • 顺序表的特点:表中元素的逻辑顺序与其物理顺序相同;

  • 假设线性表 L L L存储的起始位置为: L O C ( A ) , s i z e o f ( E l e m T y p e ) {\rm LOC(A),sizeof(ElemType)} LOC(A)sizeof(ElemType)是每个数据元素所占用存储空间的大小,则表 L L L对应的顺序存储如下图所示:

    1

  • 每个数据元素的存储位置都和线性表的起始位置相差一个和该数据元素的位序成正比的常数;

  • 线性表中的任一数据元素都可以随机存取,线性表的顺序存储结构是一种随机存取的存储结构;

  • 高级语言中通常用数组描述线性表的顺序存储结构,且数组中元素的下标从 0 0 0开始,线性表中元素的位序是从 1 1 1开始;

  • 假定线性表的元素类型为: E l e m T y p e {\rm ElemType} ElemType,则线性表的顺序存储类型描述为:

    #define MaxSize 50				// 定义线性表最大长度
    typedef struct{
        ElemType data [MaxSize];	// 顺序表的元素
        int length;					// 顺序表的当前长度
    }SqList;						// 顺序表的类型定义
    
  • 一维数组可以是静态分配的,亦可是动态分配的;

  • 静态分配:由于数组的大小和空间事先固定,一旦空间占满,再加入新的数据会产生溢出,进而导致程序崩溃;

  • 动态分配:存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,会令开辟一块更大的存储空间,代替原来的存储空间,达到扩充存储数组空间的目的;

  • 动态分配描述线性表:

    #define InitSize 100		// 表长度的初始定义
    typedef struct{	
        ElemType *data;			// 指示动态分配数组的指针
        int MaxSize,length;		// 数组的最大容量和当前个数
    }SeqList;					// 动态分配数组顺序表的类型定义
    
    // C语言的初始动态分配语句
    L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
    
    // C++初始动态分配语句
    L.data=new ElemType(InitSize);
    
  • 顺序表主要特点:随机访问,即通过首地址和元素序号可在时间 O ( 1 ) O(1) O(1)内找到指定的元素;

  • 顺序表的存储密度高,每个结点只存储数据元素;

  • 顺序表逻辑上相邻的元素物理上也相邻,故插入和删除操作需要移动大量元素;

2.2 顺序表上基本操作实现
2.2.1 顺序表插入操作
  • 在顺序表 L {\rm L} L的第 i ( 1 < = i < = L . l e n g t h + 1 ) {\rm i(1<=i<=L.length+1}) i(1<=i<=L.length+1)个位置插入新元素 e {\rm e} e

  • 插入原理:若 i {\rm i} i的输入不合法,则返回 f a l s e {\rm false} false,表示插入失败;否则,将第 i {\rm i} i个元素及其后的所有元素依次往后移动一个位置,腾出一个空位置插入新元素 e {\rm e} e,顺序表长度增加 1 1 1,插入成功,返回 t r u e {\rm true} true

  • 插入操作核心代码:

    bool ListInsert(SqList &L,int i,ElemType e){
        // 判断i的范围是否有效
        if(i<1||i>L.length+1)
            return false;
        
        // 当前存储空间已满,不能插入
        if(L.length>=MaxSize)
            return false;
        
        // 将第i个元素及之后的元素后移
        for(int j=L.length;j>=i;j--)
            L.data[j]=L.data[j-1];
        
        L.data[i-1]=e;		// 在位置i处插入e
        L.length++;			// 线性表长度加1
        return true;
    }
    
  • 顺序表插入操作时间复杂度分析:

    • 最好情况:在表尾插入,即 i = n + 1 { i=n+1} i=n+1,元素后移语句不执行,时间复杂度为 O ( 1 ) O(1) O(1)

    • 最坏情况:在表头插入,即 i = 1 {i=1} i=1,元素后移语句将执行 n n n次,时间复杂度为 O ( n ) O(n) O(n)

    • 平均情况:假设 p i ( p i = 1 / ( n + 1 ) ) p_i(p_i=1/(n+1)) pi(pi=1/(n+1))是在第 i i i个位置上插入一个结点的概率,则在长度为 n n n的线性表中插入一个结点,所需移动结点的平均次数为:
      ∑ i = 1 n + 1 p i ( n − i + 1 ) = ∑ i = 1 n + 1 1 n + 1 ( n − i + 1 ) = 1 n + 1 ∑ i = 1 n + 1 ( n − i + 1 ) = 1 n + 1 n ( n + 1 ) 2 = n 2 \sum_{i=1}^{n+1}p_i(n-i+1)=\sum_{i=1}^{n+1}\frac{1}{n+1}(n-i+1)=\frac{1}{n+1}\sum_{i=1}^{n+1}(n-i+1)=\frac{1}{n+1}\frac{n(n+1)}{2}=\frac{n}{2} i=1n+1pi(ni+1)=i=1n+1n+11(ni+1)=n+11i=1n+1(ni+1)=n+112n(n+1)=2n
      故线性表插入算法的平均时间复杂度为 O ( n ) O(n) O(n)

2.2.2 顺序表删除操作
  • 删除顺序表 L {\rm L} L中第 i ( 1 < = i < = L . l e n g t h ) {\rm i(1<=i<=L.length)} i(1<=i<=L.length)个位置的元素,用引用变量 e {\rm e} e返回;

  • 顺序表删除操作原理:若 i {\rm i} i的输入不合法,则返回 f a l s e {\rm false} false;否则,将被删除元素赋给引用变量 e {\rm e} e,并将第 i + 1 {\rm i+1} i+1个元素及其后的所有元素依次往前移动一个位置,返回 t r u e {\rm true} true

  • 删除操作核心代码:

    bool ListDelete(SqList &L,int i,Elemtype &e){
        // 判断i的范围是否有效
        if(i<1||i>L.length)
            return false;
        
        // 将被删除的元素赋值给e
        e=L.data[i-1];
        
        // 将第i个位置后的元素前移
        for(int j=i;j<L.length;j++)
            L.data[j-1]=L.data[j];
        
        // 线性表长度减1
        L.length--;
        return true;
    }
    
  • 顺序表删除操作时间复杂度分析:

    • 最好情况:删除表尾元素,即 i = n i=n i=n,则无须移动元素,时间复杂度为 O ( 1 ) O(1) O(1)

    • 最坏情况:删除表头元素,即 i = 1 i=1 i=1,则需要移动除表头元素外的所有元素,时间复杂度为 O ( n ) O(n) O(n)

    • 平均情况:假设 p i ( p i = 1 / n ) p_i(p_i=1/n) pi(pi=1/n)是删除第 i i i个位置上结点的概率,则在长度为 n n n的线性表中删除一个结点时,所需移动结点的平均次数为:
      ∑ i = 1 n p i ( n − i ) = ∑ i = 1 n 1 n ( n − i ) = 1 n ∑ i = 1 n ( n − i ) = 1 n n ( n − 1 ) 2 = n − 1 2 \sum_{i=1}^np_i(n-i)=\sum_{i=1}^n\frac{1}{n}(n-i)=\frac{1}{n}\sum_{i=1}^n(n-i)=\frac{1}{n}\frac{n(n-1)}{2}=\frac{n-1}{2} i=1npi(ni)=i=1nn1(ni)=n1i=1n(ni)=n12n(n1)=2n1
      故线性表删除算法的平均时间复杂度为 O ( n ) O(n) O(n)

2.2.3 顺序表插入和删除操作图解
  • 顺序表插入和删除操作的时间主要耗费在移动元素上,移动元素的个数取决于插入和删除元素的位置;

  • 顺序表的插入和删除操作图解如下所示:

    2

2.2.4 顺序表按值查找
  • 在顺序表 L {\rm L} L中查找第一个元素值等于 e {\rm e} e的元素,并返回位序;

  • 按值查找操作核心代码:

    int LocateElem(SqList L,ElemType e){
        int i;
        for(i=0;i<L.length;i++)
            if(L.data[i]==e)
                return i+1;		// 下标为i的元素值等于e,其位序为i+1
        return 0;
    }
    
  • 按值查找操作时间复杂度分析:

    • 最好情况:查找的元素在表头,仅需比较一次,时间复杂度为 O ( 1 ) O(1) O(1)

    • 最坏情况:查找的元素在表尾或不存在,需要比较 n n n次,时间复杂度为 O ( n ) O(n) O(n)

    • 平均情况:假设 p i ( p i = 1 / n ) p_i(p_i=1/n) pi(pi=1/n)是查找的元素在第 i ( 1 < = i < = L . l e n g t h ) {\rm i(1<=i<=L.length)} i(1<=i<=L.length)个位置上的概率,则在长度为 n n n的线性表中查找值为 e {\rm e} e的元素所需比较的平均次数为:
      ∑ i = 1 n p i × i = ∑ i = 1 n 1 n × i = 1 n n ( n + 1 ) 2 = n + 1 2 \sum_{i=1}^{n}p_i\times{i}=\sum_{i=1}^n\frac{1}{n}\times{i}=\frac{1}{n}\frac{n(n+1)}{2}=\frac{n+1}{2} i=1npi×i=i=1nn1×i=n12n(n+1)=2n+1
      故线性表按值查找操作的平均时间复杂度为 O ( n ) O(n) O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/400109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

脑机接口科普0017——飞米

本文禁止转载&#xff01;&#xff01;&#xff01;&#xff01; 在我们的九年制义务教育体系中&#xff0c;我们知道纳米是个很小的单位&#xff0c;一般进行单位制的转换的时候&#xff0c;最小就只能到达纳米级别了。 1nm 10^-9 m 这会给学生造成一种误解。认为纳米就是…

搭建兰空图床(Lsky Pro)-docker

兰空图床(Lsky Pro) 官方网站&#xff1a;https://www.lsky.pro/ GitHub&#xff1a;https://github.com/lsky-org/lsky-pro 一, 安装docker-compose 下载-授权 #下载 国内地址 curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-una…

dl----算法常识100例

1.depthwise卷积&&Pointwise卷积 depthwise与pointwise卷积又被称为Depthwise Separable Convolution&#xff0c;与常规卷积不同的是此卷积极大地减少了参数数量&#xff0c;同时保持了模型地精度&#xff0c;depthwise操作是先进行二维平面上地操作&#xff0c;然后利…

nginx的学习

1. 我们今天的目标是学习 了解认识nginx的基本结构和语法学习经典案例 2. Nginx是什么 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;Nginx是由俄罗斯的人开发的&#xff0c;因它的稳定性、丰富的功能集…

爬虫(二)解析数据

文章目录1. Xpath2. jsonpath3. BeautifulSoup4. 正则表达式4.1 特殊符号4.2 特殊字符4.3 限定符4.3 常用函数4.4 匹配策略4.5 常用正则爬虫将数据爬取到后&#xff0c;并不是全部的数据都能用&#xff0c;我们只需要截取里面的一些数据来用&#xff0c;这也就是解析爬取到的信…

通过测试驱动开发(TDD)的方式开发Web项目

最近在看一本书《Test-Driven Development with Python》&#xff0c;里面非常详细的介绍了如何一步一步通过测试驱动开发(TDD)的方式开发Web项目。刚好这本书中使用了我之前所了解的一些技术&#xff0c;Django、selenium、unittest等。所以&#xff0c;读下来受益匪浅。 我相…

NFT的前景,元宇宙的发展

互联网的普及和数字技术的广泛应用&#xff0c;成为消费升级的新动力&#xff0c;在不断创造出更好的数字化生活的同时&#xff0c;也改变了人们的消费习惯、消费内容、消费模式&#xff0c;甚至是消费理念&#xff0c;数字经济时代的文化消费呈现出新的特征。 2020年有关机构工…

性能优化的核心思路

性能优化的本质是良好的用户体验和有限的资源之间的矛盾。核心思路【1】堆硬件 优化软件&#xff08;算法、步骤&#xff09;【2】开源&#xff08;堆机器&#xff09; 节流&#xff08;提高资源利用率&#xff0c;少占资源&#xff09;【3】输入、计算、输出【4】权衡核心思想…

谷粒学院开发(二):教师管理模块

前后端分离开发 前端 html, css, js, jq 主要作用&#xff1a;数据显示 ajax后端 controller service mapper 主要作用&#xff1a;返回数据或操作数据 接口 讲师管理模块&#xff08;后端&#xff09; 准备工作 创建数据库&#xff0c;创建讲师数据库表 CREATE TABLE edu…

git 当有人邀请你加入项目(gitee)

第一步&#xff0c;找到仓库地址 https://gitee.com/xxxxxxxxxxxxxxxx/abcd.git https://gitee.com/xxxxxxxxxxxxxxxx/abcd.git 2&#xff0c;打开git bush git clone https://gitee.com/xxxxxxxxxxxxxxxx/abcd.git 这条命令新建一个名为abcd&#xff08;也就是项目目录结尾…

python操作频谱仪(是德科技N9030B)

由于工作需要&#xff0c;需要针对产品进行一些自动化的测试&#xff0c;其中就包含了验证开机启动或者长时间运行时候对射频、晶振频率等等一些列进行获取频率或者功率的偏差。这里就需要用到了频谱仪&#xff0c;可以使用脚本连接到频谱仪进行循环对数据的采集等等。直接开始…

Python中的property介绍

Python中的property介绍 Python中进行OOP&#xff08;面向对象程序设计&#xff09;时&#xff0c;获取、设置和删除对象属性&#xff08; attribute&#xff09;的时候&#xff0c;常常需要限制对象属性的设置和获取&#xff0c;比如设置为只读、设置取值范围限制等&#xff…

28个案例问题分析---06---没有复用思想的接口和sql--mybatis,spring

复用思维故事背景没有复用的接口没有复用思想的接口优化方案问题一优化获取所有的课程获取某个人创建的课程问题二优化升华故事背景 项目里有两处没有复用的思想的体现。在这里进行总结并且进行优化。以这种思维方式和习惯来指导我们进行开发工作。 没有复用的接口 通过查看代…

PowerShell远程代码执行漏洞(CVE-2022-41076)分析与复现

漏洞概述PowerShell&#xff08;包括Windows PowerShell和PowerShell Core&#xff09;是微软公司开发的任务自动化和配置管理程序&#xff0c;最初只是一个 Windows 组件&#xff0c;由命令行 shell 和相关的脚本语言组成。后于2016年8月18日开源并提供跨平台支持。PowerShell…

网络安全与信息安全的主要区别讲解-行云管家

生活中工作中&#xff0c;我们经常可以听到信息安全与网络安全这两个词语&#xff0c;但很多小伙伴对于两者区分不清楚&#xff0c;今天我们小编就给大家来简单讲解一下这两者的主要区别吧&#xff01; 网络安全与信息安全的主要区别讲解 1、定义不同 网络安全是指网络系统的…

总结:Linux内核相关

一、介绍看eBPF和Cilium相关内容时&#xff0c;碰到Cilium是运行在第 3/4 层&#xff0c;不明白怎么做到的&#xff0c;思考原理的时候就想到了内容&#xff0c;本文记录下内核相关知识。https://www.oschina.net/p/cilium?hmsraladdin1e1二、Linux内核主要由哪几个部分组成Li…

前端——6.文本格式化标签和<div>和<span>标签

这篇文章&#xff0c;我们来讲一下HTML中的文本格式化标签 目录 1.文本格式化标签 1.1介绍 1.2代码演示 1.3小拓展 2.div和span标签 2.1介绍 2.2代码演示 2.3解释 3.小结 1.文本格式化标签 在网页中&#xff0c;有时需要为文字设置粗体、斜体和下划线等效果&#xf…

vuedraggable的使用

Draggable为基于Sortable.js的vue组件&#xff0c;用以实现拖拽功能。 特性 支持触摸设备 支持拖拽和选择文本 支持智能滚动 支持不同列表之间的拖拽 不以jQuery为基础 和视图模型同步刷新 和vue2的国度动画兼容 支持撤销操作 当需要完全控制时&#xff0c;可以抛出所有变化 可…

【国际化】vue2+uniapp实现国际化

文章目录前言一、什么是国际化&#xff1f;二、使用步骤1.创建locale文件夹2.创建国际化JSON文件3.引入国际化总结前言 国际化其实是拓展你的应用的受众人群的一种方式&#xff0c;有利于你的项目应用范围更广&#xff0c;uniapp和vue官方文档都有针对于国际化有专门的文档&am…

WIFI电子标签参数

一、4.2寸WIFI电子标签参数 型号 PW42R_V1 尺寸(mm) 104.95*95.93*15.2mm 显示技术 3色墨水屏显示技术 可视区域(mm) 84.6*63.4 分辨率(像素) 400*300 像素尺寸(mm) 0.212*0.212 单点颜色 黑/白/红 视角 180 工作温度 0 - 40℃ 重量 150g 电池 CR2477*6 …