【数据结构】一文讲解线性表之顺序表概念及其基本操作(附C语言源码)

news2024/11/9 2:10:49
前文我们讲过数据结构的三个部分:数据、数据元素和数据结构以及数据结构的三要素:逻辑结构、物理结构和数据运算。现在我们从三个组成部分和三要素讲解

线性表的定义和基本操作

定义

线性表是一个抽象的概念,一般具有相同数据类型的n(n>=0)个数据元素的有限序列,其中n为表长。(是不是感觉类似数组,但数组不是线性表,但也具有线性表的一些特性)

线性表指的是数据元素通过线性逻辑结构连接的一种数据结构。

数据元素之间是线性关系,形如A->B->C…->N

基本概念

  • 空表 n=0,线性表长度为0
  • 位序 线性表中第i个数据元素
  • 表头元素 线性表中第一个数据元素
  • 表尾元素 线性表中最后一个数据元素
  • 数据元素之间存在一对一的线性关系,即每个元素(除第一个外)有且仅有一个前驱,每个元素(除最后一个外)有且仅有一个后继。
基本操作

线性表的基本操作指的是几个基本的数据运算,一般都有如下几个操作:

  • 建立表
  • 初始化表
  • 插入
  • 删除
  • 查找

下面就讲解一下线性表中的线性表中的顺序表的概念以及基本操作

顺序表

线性表定义了数据结构的逻辑结构为线性,而顺序表则定义其物理结构为连续的,顺序的线性表。即用顺序储存的方式实现线性表(逻辑上相邻的元素在顺序上也相邻)

顺序表的建立与初始化
*******************************静态分配******************************************
// 定义线性表的最大长度
#define MAX_SIZE 100

// 定义线性表的结构体
typedef struct {
	ElemType data[MAX_SIZE]; // 存储数据的数组   数组的存储方式为顺序的
	int length; // 当前线性表的长度 
} SeqList; //定义顺序表的名字

// 初始化线性表 
void InitList(SeqList *L) { 
	for(int i=0 ; i < MAX_SIZE ; i++) {
		L.data[i] = 0 ;//初始化所有元素为0
	}
	L.length = 0; // 初始长度为0 
}

**特别注意的是ElemType变量,它不是一个实际的数据类型,指代任意一种数据类型,例如int float double等**

静态分配的顺序表长度固定,不可拓展,实际应用中不方便,我们更多采用动态分配创建顺序表
*******************************动态分配******************************************
// 定义线性表的默认最大长度
#define MAX_SIZE 100

// 定义线性表的结构体
typedef struct {
	ElemType *data;  // 指示动态分配的指针 ElemType表示任意数据类型(例如int) 
	int length;      // 当前顺序表的长度 
	int MaxSize;     //顺序表最大容量
} SeqList; 

// 初始化线性表 
void InitList(SeqList *L) { 
	L.data=(ElemType *)malloc(MAX_SIZE*sizeof(ElemType));//分配连续空间
	L.length = 0; // 初始长度为0 
	L.MaxSize = MAX_SIZE;     //顺序表最大容量
}

//增加动态数组的长度
void IncreaseSize(SeqList &L,int len){
	ElemType *p=L.data;
	L.data=(ElemType *)malloc((L.MAX_SIZE+len)*sizeof(ElemType));
	for(int i=0 ; i < L.length ; i++){
		L.data[i]=p[i];
	}
	L.MaxSize=L.MaxSize + len;
	free(p);
}

特别注意的是ElemType变量,它不是一个实际的数据类型,指代任意一种数据类型,例如int float double等

顺序表的插入
//在顺序表L的第i个位置插入元素e
bool ListInsert(SeqList &L,int i,ElemType){
	if(i<1||i>L.length+1)						//判断i的范围是否在可插入范围内
		return flase;							//不在范围内插入失败
	if(L.length>=MaxSize)						//判断当前空间是否满了,满了则不能插入
		return flase;							//空间已满,插入失败
	for(int j = L.length ; j>=i ;j--){			//将插入位置之后的元素后移
		L.data[j]=L.data[j-i];
	}
	L.data[i-1]=e;								//在i的位置插入元素e
	L.length++;									//顺序表长度+1
	return true;插入成功
}

时间复杂度分析,时间复杂度一般关注最深层的代码,则为for循环中的移位代码。

  • 最好情况 元素插入到顺序表尾部,不需要移位则时间复杂度为O(1)
  • 最坏情况 元素插入到顺序表头部,需要将原有n个元素向后移动一位,时间复杂度为O(n)
  • 平均情况 新元素插入到每个位置的概率相等,可得平均移位次数n/2,时间复杂度为O(n)
顺序表的删除
//将表中的第i个元素删除
bool ListDelete(SeqList &L,int i){
	if(i<1||i>L.length+1)							//判断i的范围是否在可插入范围内
		return flase;								//不在范围内,删除失败
	for(int j=i;j<L.length;j++){					//将删除元素后续的元素向前移
		L.data[j-1]=L.data[j];
	}
	L.length--;										//顺序表长度-1
	return true;									//删除成功
}

时间复杂度分析,时间复杂度一般关注最深层的代码,则为for循环中的移位代码。

  • 最好情况 元素删除的是顺序表尾部元素,不需要移位则时间复杂度为O(1)
  • 最坏情况 元素删除的是顺序表头部元素,需要将原有n-1个元素向前移动一位,时间复杂度为O(n)
  • 平均情况 新元素插入到每个位置的概率相等,可得平均移位次数(n-1)/2,时间复杂度为O(n)
顺序表的查找
按位查找
//按位查找-查找顺序表第i位的元素
ElemType GetElem(SeqList &L,int i){
	return L.data[i-1];
}

时间复杂度分析,由于顺序表的存储位置是连续的,因此按位查找可以直接索引取得,时间复杂度仅位O(1);

按值查找
//按值查找,查找顺序表中e元素所在位置
int LocateElem(SeqList &L,ElemType e){
	for(int i=0;i<L.length;i++){
		if(L.data[i]==e)
			return i+1;
	}
	return 0
}

时间复杂度分析,时间复杂度一般关注最深层的代码,则为for循环中的遍历代码。

  • 最好情况 第一个元素为待查找元素,不需要后续遍历则时间复杂度为O(1)
  • 最坏情况 最后一个元素为待查找元素,需要遍历n个元素,时间复杂度为O(n)
  • 平均情况 新元素插入到每个位置的概率相等,可得平均移位次数(n+1)/2,时间复杂度为O(n)
顺序表的特点
  • 便于访问,能够立刻在O(1)的时间复杂度中找到待访问的值
  • 数据集中,数据的物理位置相互贴近,且每个存储节点只存储数据
  • 加长、插入、删除等操作复杂,需要大量平移元素位置

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

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

相关文章

【解决办法】无法使用右键“通过VSCode打开文件夹”

个人博客&#xff1a;苏三有春的博客 前言 作者的编程环境为VScode&#xff0c;工作时常使用VScode打开整个工程文件夹。如果先打开VScode再从VScode中选择文件夹打开效率太慢&#xff0c;作者一般使用的方式是右键文件夹&#xff0c;直接选择"通过code打开文件夹"…

推荐一款ETCD桌面客户端——Etcd Workbench

Etcd Workbench 我相信很多人在开始管理ETCD的时候都去搜了Etcd客户端工具&#xff0c;然后找到了官方的Etcd Manager&#xff0c;但用完之后发现它并不好用&#xff0c;还不支持多连接和代码格式化&#xff0c;并且已经好几年不更新了&#xff0c;于是市面上就有了好多其他客…

Docker配置及简单应用

谈论/理解 Docker 的常用核心部分&#xff0c;以下皆在 Ubuntu 操作系统下进行 1 国内源安装 Docker-ce 1.1 配置 Linux 内核流量转发 因为docker和宿主机的端口映射&#xff0c;本质是内核的流量转发功能&#xff0c;所以要对其进行配置 1.1.1 未配置流量转发 如果没有配置流…

(十二)JavaWeb后端开发——MySQL数据库

目录 1.数据库概述 2.MyQSL 3.数据库设计 DDL 4.MySQL常见数据类型 5.DML 1.数据库概述 数据库&#xff1a;DataBase(DB)&#xff0c;是存储和管理数据的仓库 数据库管理系统&#xff1a;DataBase ManagementSystem(DBMS)&#xff0c;操纵和管理数据库的大型软件 SQL&a…

fastadmin后台列表根据所选中的行统计指定字段|fastadmin点击checkbox或反选统计某个字段的值

当选中对应行时&#xff0c;统计选中行的用户注册数和用户点击数。 此项功能需要有 点击全选触发事件、点击反选触发事件、勾选某一行触发事件、反选某一行触发事件&#xff0c;用到fastadmin自带的表格事件功能&#xff0c;参考&#xff1a;https://doc.fastadmin.net/doc/19…

stm32使用串口DMA实现数据的收发

前言 DMA的作用就是帮助CPU来传输数据&#xff0c;从而使CPU去完成更重要的任务&#xff0c;不浪费CPU的时间。 一、配置stm32cubeMX 这两个全添加上。参数配置一般默认即可 代码部分 只需要把上期文章里的HAL_UART_Transmit_IT(&huart2,DATE,2); 全都改为HAL_UART_Tra…

轨迹规划中优化预测:学习多个初始解的优化器

Abstract 在许多应用中&#xff0c;如机器人控制、自动驾驶和投资组合管理&#xff0c;需要在严格的运行时间限制下连续地解决相似的优化问题。在这种情况下&#xff0c;局部优化方法的性能对初始解的质量非常敏感&#xff1a;不良的初始化可能会导致收敛缓慢或得到次优解。为…

05 SQL炼金术:深入探索与实战优化

文章目录 SQL炼金术&#xff1a;深入探索与实战优化一、SQL解析与执行计划1.1 获取执行计划1.2 解读执行计划 二、统计信息与执行上下文2.1 收集统计信息2.2 执行上下文 三、SQL优化工具与实战3.1 SQL Profile3.2 Hint3.3 Plan Baselines3.4 实战优化示例 SQL炼金术&#xff1a…

JS封装随机生成一个颜色值工具函数

本文给大家带来的是封装的一个随机生成一个颜色值的工具函数。案例中提供了4个不同的调用函数&#xff0c;但实现的功能本质上都是一样的&#xff0c;开箱即用&#xff0c;随调随用。 //方法一 function getRandomColor() { //随机颜色return #${Math.floor(Math.random() * …

CESS 正式加入政府区块链协会 (GBA) ,出席 Blockchain Infrastructure 大会

北京时间 11 月 6 日&#xff0c;特朗普赢得 2024 年美国总统大选。与此同时&#xff0c;我们很高兴地宣布&#xff0c;CESS 已正式加入政府区块链协会 (GBA)。GBA 是一个全球性协会&#xff0c;致力于将区块链专业人士汇聚在一起&#xff0c;共同推动区块链技术在政府、金融和…

ARXML汽车可扩展标记性语言规范讲解

ARXML: Automotive Extensible Markup Language &#xff08;汽车可扩展标记语言&#xff09; xmlns: Xml name space &#xff08;xml 命名空间&#xff09; xsd: Xml Schema Definition (xml 架构定义) 1、XML与HTML的区别&#xff0c;可扩展。 可扩展&#xff0c;主要是…

数据结构_哈夫曼树及其应用

构造算法的例子 构造算法的实现 初始化&#xff0c;置权值 int i, m, s1, s2;m 2 * n - 1;for (i 1; i < m; i){HT[i].lch 0;HT[i].rch 0;HT[i].parent 0;}for (i 1; i < n; i){cin >> HT[i].weight;}合并结点 // 创建哈夫曼树for (i n 1; i < m; i){s1…

基于AI深度学习的中医针灸实训室腹针穴位智能辅助定位系统开发

在中医针灸的传统治疗中&#xff0c;穴位取穴的精确度对于治疗效果至关重要。然而&#xff0c;传统的定位方法&#xff0c;如体表标志法、骨度折量法和指寸法&#xff0c;由于观察角度、个体差异&#xff08;如人体姿态和皮肤纹理&#xff09;以及环境因素的干扰&#xff0c;往…

esp32学习:利用虫洞ESP32开发板,快速实现无线图传

我们的虫洞开发板&#xff0c;能够完美运行esp who AI代码&#xff0c;所以实现无线图传那是非常容易的&#xff0c;我们先看看examples目录&#xff1a; 里面有比较多的web例程&#xff0c;在这些例程下&#xff0c;稍作修改&#xff0c;就可以快速实现我的图传无线功能&#…

力扣排序455题(分发饼干)

假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。 但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i],这是能 让孩子们满足胃口的饼干的最小尺寸;并且每块饼 干j&#xff0c;都有一个尺寸 s[j]。如果 s[j]> g[i]&…

【论文复现】基于深度学习的手势识别算法

本文所涉及所有资源均在这里可获取。 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐、摄影的一位博主。 &#x1f4d7;本文收录于论文复现系列&#xff0c;大家有兴趣的可以看一看…

ChatGPT键盘快捷键(按ctrl + /呼出)

文章目录 ChatGPT键盘快捷键- 打开新聊天: Ctrl Shift O- 聚焦聊天输入: Shift Esc- 复制最后一个代码块: Ctrl Shift ;- 复制最后一个回复: Ctrl Shift C- 设置自定义指令: Ctrl Shift I- 切换边栏: Ctrl Shift S- 删除聊天: Ctrl Shift ⌫- 显示快捷方式: Ctrl …

超详细:Vue入门

Vue(发音为 /vjuː/&#xff0c;类似 view)是近些年比较流行的前端框架之一&#xff0c;和 React、Angular 并称为前端三大框架。其中 Vue 简单易学的特点成为国内主流&#xff0c;很多公司已经把它列为一 个前端开发人员必须要掌握的技术点了。 Vue 简介 Vue2.x官网 Vue3.x …

鸿蒙next打包流程

目录 下载团结引擎 添加开源鸿蒙打包支持 打包报错 路径问题 安装DevEcoStudio 可以在DevEcoStudio进行打包hap和app 包结构 没法直接用previewer运行 真机运行和测试需要配置签名,DevEcoStudio可以自动配置, 模拟器安装hap提示报错 安装成功,但无法打开 团结1.3版本新增工具…

你是我的映射,我是你的值:C++ map 中的心灵共鸣

文章目录 map的概念一、map的使用1. 插入删除相关1&#xff09;插入(1) 插入语法(1) 插入语法 2&#xff09;删除 二. map的遍历三、map重载operator[]四、小试&#x1f402;&#x1f52a;1. 前K个高频单词2. 单词识别 总结 map的概念 map是key_value的模型&#xff1a; 一棵树…