【数据结构】线性表 顺序表(动态、静态分配,插入删除查找基本操作)解析+完整代码

1.线性表的基本概念

  • 定义

    线性表(Linear List)是具有相同数据类型的n个数据元素的有限序列

    • n为表长,n=0时线性表是个空表
  • 前驱、后继

    • 前驱:其中一个数据元素的前一个元素。第一个元素没有前驱。
    • 后继:其中一个数据元素的后一个元素。最后一个元素没有后继。
  • 存储/物理结构

    • 顺序表(顺序存储)
    • 链表(链式存储)

2.顺序表

2.1 顺序表的定义

  • 顺序表定义

    用顺序存储方式实现线性表的储存。

    是用一组地址连续的存储单元依次存储线性表中的数据元素。

    • 特点:

      1.表中元素的逻辑顺序与物理顺序相同。

      2.可以随机存取——知道顺序表起始位置LOC(A)和每个元素所占内存的大小sizeof(ElemType)后,可知道任意一个元素的位置。

  • 优点

    1.可随机访问,O(1)时间内找到指定元素;

    2.存储密度高,每个结点只存储数据元素。

  • 缺点

    1.元素的插入和删除要移动大量数据元素。

    2.需要连续存储空间,不够灵活。

2.1.1 静态分配
//静态分配结构存储
#define MaxSize 10 //最大长度
typedef struct{int data[MaxSize]; //静态数组存放数据元素int length; //顺序表当前长度
}SqList; //顺序表类型定义//静态分配初始化
void InitList(SqList &L){L.Length=0;
}
  • 如果数组存满怎么办?

    没办法了,因为顺序表表长刚开始确定后就无法改变,∴有了动态分配

2.1.2 动态分配
//动态分配结构存储
#define InitSize 100 //表长度的初始定义
typedef struct{ElemType *data; //指示动态分配数组的指针int MaxSize; //最大容量int length; //当前个数
}SeqList;//动态分配初始化
void InitList(SeqList &L){L.data=(ElemType*)malloc(MaxSize*sizeof(ElemType));L.length=0;L.MaxSize=InitSize;
}

C动态分配语句

L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);
free(L.data);

C++动态分配语句

L.data=new ElemType[InitSize];
delete[]指针变量名;
或
delete 指针变量名;
  • 增加动态数组长度

    void IncreaseSize(SeqList &L,int len){int *p=L.data; //将表中数据存储到p中L.data=(int*)malloc((L.MaxSize+len)*sizeof(int)); //开辟新空间for(int i=0;i<L.length;i++){L.data[i]=p[i]; //数据复制到新区域}L.MaxSize=L.MaxSize+len;free(p);
    }
    
  • 注:动态分配不是链式存储,同样顺序存储,只是空间大小可变。

2.2 顺序表的插入

  • 原理

    在线性表L的第i个位置插入元素e:

    将第i个元素及其后面的所有元素向后移一位,腾出空位插e。

    >

//在L的位序i处插入元素e
bool ListInsert(SqList &L,int i,int 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;L.length++;return true;
}
  • 时间复杂度

    • 最好情况:在表尾插入,元素后移不用执行,O(1)。
    • 最坏情况:在表头插入,元素后移执行n次,O(n)。
    • 平均情况:O(n/2),即O(n)。

2.3 顺序表的删除

  • 原理

    删除顺序表L中的第i个元素:

    将被删元素赋给引用变量e,将第i+1个元素及其后的所有元素往前移一位。

//删除L中的第i个元素,并用返回
bool ListDelete(SqList &L,int i,ElemType &e){if(i<1||i>L.length)return false;e=L.data[i-1]; //被删元素给引用变量//被删元素后的元素依次后移for(int j=i;j<L.length;j++){L.data[j-1]=L.data[j];}L.length--;return true;
}
  • 时间复杂度

    • 最坏情况:删除表尾元素,无需移动元素,O(1)。
    • 最好情况:删除表头元素,需移动除表尾外的所有元素,O(n)。
    • 平均情况:O(n/2),即O(n)。

2.4 顺序表的查找

2.4.1 按位查找
ElemType GetElem(SqList L,int i){return L.data[i-1];
}
  • 时间复杂度:O(1)
2.4.2 按序查找
int LocateElem(SqList L,ElemType e){int i;for(i=0;i<L.length;i++){if(L.data[i]==e)return i+1; //找到了返回位序}return 0; //没找到返回0
}
  • 时间复杂度:O(n)

*完整代码 顺序表静态存储

//顺序表 静态分配 线性表下标从0开始
#include<stdio.h>#define ElemType int//静态结构体
#define MaxSize 99
typedef struct {ElemType data[MaxSize];int length;
}SqList;//初始化
void InitList(SqList &L)
{L.length = 0;
}//求表长
int Length(SqList &L) 
{return L.length;
}//按值查找
int LocateElem(SqList &L,ElemType e) 
{for (int i = 0; i < L.length; i++) {if (L.data[i] == e) {return i + 1;}}return 0;
}//按位查找
int GetItem(SqList& L, int i) 
{return L.data[i-1]; //i是位序,而顺序表从0开始存的,所以i要-1
}//插入操作
bool ListInsert(SqList& L, int i, ElemType e) 
{if (i<1 || i>L.length)return false;if (L.length >= MaxSize)return false;for (int j = L.length; j >= i; j--) {L.data[j] = L.data[j - 1];}L.data[i-1] = e; L.length++;return true;
}//删除操作
bool ListDelete(SqList& L, int i, ElemType& e) 
{if (i<1 || i>L.length)return false;e = L.data[i-1];for (int j = i; j <L.length; j++) {L.data[j-1] = L.data[j];}L.length--;return true;
}//判空操作
bool Empty(SqList& L)
{if (L.length == 0)return true;elsereturn false;
}//销毁操作
void DestroyList(SqList &L)
{L.length = 0;
}//输出
void PrintList(SqList& L) 
{for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");
}int main()
{SqList L;InitList(L);//赋值for (int i = 0; i < 10; i++){L.data[i] = i;L.length++;}PrintList(L);printf("插入:\n");int e = -1, pos = 4;ListInsert(L, pos , e);PrintList(L);printf("删除:\n");int a;ListDelete(L, pos, a);PrintList(L);printf("%d\n", a);printf("按值查找:\n");pos = LocateElem(L, 5);printf("%d\n", pos);printf("按位查找:\n");printf("%d", GetItem(L, 3));
}

请添加图片描述

*完整代码 顺序表动态存储

//顺序表 动态分配 
#include<stdio.h>
#include <stdlib.h>#define ElemType int//静态结构体
#define InitSize 2
typedef struct {ElemType *data;int length;int MaxSize;
}SeqList;//初始化
void InitList(SeqList& L)
{L.data = (ElemType*)malloc(InitSize * sizeof(ElemType));L.length = 0;L.MaxSize = InitSize;
}//增加动态数组长度
void IncreaseSize(SeqList& L, int len) {int* p = L.data; //将表中数据存储到p中L.data = (int*)malloc((L.MaxSize + len) * sizeof(int)); //开辟新空间for (int i = 0; i < L.length; i++){L.data[i] = p[i]; //数据复制到新区域}L.MaxSize = L.MaxSize + len;free(p);
}//求表长
int Length(SeqList& L)
{return L.length;
}//按值查找
int LocateElem(SeqList& L, ElemType e)
{for (int i = 0; i < L.length; i++){if (L.data[i] == e){return i + 1;}}return 0;
}//按位查找
int GetItem(SeqList& L, int i)
{return L.data[i - 1]; //i是位序,而顺序表从0开始存的,所以i要-1
}//插入操作
bool ListInsert(SeqList& L, int i, ElemType e)
{if (i<1 || i>L.length)return false;if (L.length >= L.MaxSize)return false;for (int j = L.length; j >= i; j--){L.data[j] = L.data[j - 1];}L.data[i - 1] = e; L.length++;return true;
}//删除操作
bool ListDelete(SeqList& L, int i, ElemType& e)
{if (i<1|| i>L.length)return false;e = L.data[i - 1];for (int j = i; j < L.length; j++){L.data[j - 1] = L.data[j];}L.length--;return true;
}//判空操作
bool Empty(SeqList& L)
{if (L.length == 0)return true;elsereturn false;
}//销毁操作
void DestroyList(SeqList& L)
{free(L.data);L.data = NULL; // 避免悬挂指针L.length = 0;
}//输出
void PrintList(SeqList& L)
{for (int i = 0; i < L.length; i++){printf("%d ", L.data[i]);}printf("\n");
}int main()
{SeqList L;InitList(L);IncreaseSize(L, 9);//赋值for (int i = 0; i < 10; i++){L.data[i] = i;L.length++;}PrintList(L);printf("插入:\n");int e = -1, pos = 5;ListInsert(L, pos, e);PrintList(L);printf("删除:\n");int a;ListDelete(L, pos, a);PrintList(L);printf("%d\n", a);printf("按值查找:\n");pos = LocateElem(L, 5);printf("%d\n", pos);printf("按位查找:\n");printf("%d", GetItem(L, 3));DestroyList(L);
}

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

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

相关文章

使用R语言进行多元线性回归分析-多重共线的诊断

一、数据集 序号X1x2x3x4Y序号X1x2x3X4Y12666078.57831224472.51229155274.31954182293.12356850104.3111047426115.92143184787.6111140233483.8155263395.971266912113.311655922109.2111368812109.410771176102.73       1、从中选取主要变量&#xff0c;建立与因变…

SQL注入漏洞解析--less-46

我们先看一下46关 他说让我们先输入一个数字作为sort,那我们就先输入数字看一下 当我们分别输入1&#xff0c;2&#xff0c;3可以看到按照字母顺序进行了排序&#xff0c;所以它便是一个使用了order by语句进行排序的查询的一种查询输出方式 当输入时出现报错提示&#xff0c;说…

AI一键生成3D模型!

一、Genie Genie 是 Luma AI 推出的一个文本到 3D 的生成模型&#xff0c;可以在 10 秒生成 4 款 3D 模型&#xff0c;自动精修后质感非常逼真&#xff0c;目前支持免费使用。 此次的 1.0 版本更新后将生成功能由 Discord 转到了单独的网页&#xff0c;使用起来更方便&#x…

无法访问云服务器上部署的Docker容器(二)

说明&#xff1a;记录一次使用公网IP 接口地址无法访问阿里云服务接口的问题&#xff1b; 描述 最近&#xff0c;我使用Docker部署了jeecg-boot项目&#xff0c;部署过程都没有问题&#xff0c;也没有错误信息。部署完成后&#xff0c;通过下面的地址访问后端Swagger接口文档…

CleanMyMac4苹果Mac电脑全面、高效的系统清理工具

CleanMyMac 4 for Mac是一款专为Mac用户设计的系统清理和优化工具。它具备多种功能&#xff0c;旨在帮助用户轻松管理和释放Mac上的磁盘空间&#xff0c;同时提升系统性能。 系统垃圾清理&#xff1a;CleanMyMac 4能够深入扫描Mac的每一个角落&#xff0c;智能识别并清除不需要…

LDR6020双盲插音频随便插充电听歌随便插

随着智能手机的普及和功能的日益丰富&#xff0c;手机已经成为我们日常生活中不可或缺的一部分。音乐、电影、游戏等娱乐内容更是丰富了手机的使用体验。而在这其中&#xff0c;音频转接器的作用愈发凸显&#xff0c;特别是在边听边充的场景下&#xff0c;一款高效且便捷的手机…

实践航拍小目标检测,基于轻量级YOLOv8n开发构建无人机航拍场景下的小目标检测识别分析系统

关于无人机相关的场景在我们之前的博文也有一些比较早期的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《deepLabV3Plus实现无人机航拍目标分割识别系统》 《基于目标检测的无人机航拍场景下小目标检测实践》 《助力环保河道水质监测&#xff0c;基于yolov…

小龙虾优化算法COA求解不闭合SD-MTSP,可以修改旅行商个数及起点(提供MATLAB代码)

一、小龙虾优化算法COA 小龙虾优化算法&#xff08;Crayfsh optimization algorithm&#xff0c;COA&#xff09;由Jia Heming 等人于2023年提出&#xff0c;该算法模拟小龙虾的避暑、竞争和觅食行为&#xff0c;具有搜索速度快&#xff0c;搜索能力强&#xff0c;能够有效平衡…

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树

★【递归】【构造二叉树】Leetcode 106.从中序与后序遍历序列构造二叉树 105. 从前序与中序遍历序列构造二叉树 106.从中序与后序遍历序列构造二叉树:star:思路分析递归解法 105. 从前序与中序遍历序列构造二叉树递归解法 ---------------&#x1f388;&#x1f388;题目链接&a…

计算机网络-IP网络划分专题

1.8421法二转十&#xff08;连加&#xff09;或十转二&#xff08;连减&#xff09; 如下图&#xff1a; 2.IP地址 4个字节32位。每一个8位组用0~255表示。因此&#xff0c;最小的IP地址值为0.0.0.0&#xff0c;最大的地址值为255.255.255.255。 3.位数和个数的关系&#xff…

内核中断体系概括

文章目录 前言一、Linux的中断机制1、分类2、代码结构 二、中断的工作流程1、中断的工作流程2、Linux 中中断的工作流程3、中断的代码实现过程 三、内核中断体系结构 前言 本文对内核中断进行概括以及讲述中断的具体实现方法在内核是怎么做的&#xff0c;会结合内核源码中的一…

【Flink】Flink 中的时间和窗口之窗口(Window)

1. 窗口的概念 Flink是一种流式计算引擎&#xff0c;主要是来处理无界数据流&#xff0c;数据流的数据是一直都有的&#xff0c;等待流结束输入数据获取所有的流数据在做聚合计算是不可能的。为了更方便高效的处理无界流&#xff0c;一种方式就是把无限的流数据切割成有限的数…

c语言-day1(ubuntu操作系统及指令)

1&#xff1a;思维导图 2&#xff1a; &#xff08;1&#xff09;&#xff1a; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; &#xff08;5&#xff09;

通过盲注脚本复习sqllabs第46关 order by 注入

sql-lab-46 order by 注入是指其后面的参数是可控的&#xff0c; order by 不同于我们在 where 后的注入点&#xff0c;不能使用 union 等注入&#xff0c;其后可以跟接 报错注入 或者 时间盲注。 数字型order by注入时,语句order by2 and 12,和order by2 and 11显示的结果一…

前端框架的CSS模块化(CSS Modules)

创作纪念日之际&#xff0c;来给大家分享一篇文章吧 聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们…

Vue前端对请假模块——请假开始时间和请假结束时间的校验处理

开发背景&#xff1a;Vueelement组件开发 业务需求&#xff1a;用户提交请假申请单&#xff0c;请假申请的业务逻辑处理 实现&#xff1a;用户选择开始时间需要大于本地时间&#xff0c;不得大于请假结束时间&#xff0c;请假时长根据每日工作时间实现累加计算 页面布局 在前…

二进制部署k8s之网络部分

1 CNI 网络组件 1.1 K8S的三种接口 CRI 容器运行时接口 docker containerd podman cri-o CNI 容器网络接口 flannel calico cilium CSI 容器存储接口 nfs ceph gfs oss s3 minio 1.2 K8S的三种网络 节点网络 nodeIP 物理网卡的IP实现节点间的通信 Pod网络 podIP Pod与Po…

视频和音频使用ffmpeg进行合并和分离(MP4)

1.下载ffmpeg 官网地址&#xff1a;https://ffmpeg.org/download.html 2.配置环境变量 此电脑右键点击 属性 - 高级系统配置 -高级 -环境变量 - 系统变量 path 新增 文件的bin路径 3.验证配置成功 ffmpeg -version 返回版本信息说明配置成功4.执行合并 ffmpeg -i 武家坡20…

GOOGLE Colab Pro会员订阅开通购买付费充值教程

一、简介 colab由谷歌团队开发&#xff0c;用于机器学习、数据分析&#xff0c;教育等目的&#xff0c;他的会员也非常的昂贵&#xff0c;最基本的套餐要10美金&#xff0c;最高要50美金一个月&#xff0c;如何省钱&#xff0c;往下看。 一般来说土区的价格比较便宜&#xff0…

Day02:Web架构前后端分离站Docker容器站集成软件站建站分配

目录 常规化站点部署 站库分离 前后端分离 集成软件搭建Web应用 Docker容器搭建Web应用 建立分配站 静态 与 伪静态 总结 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服务/负载均衡等 安全产品&#xff1a;CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗…