数据结构——第二章 线性表(1)——顺序结构

news2024/11/17 8:38:47

线性表

  • 1. 线性表
    • 1.1 线性表的定义
      • 1.1.1 访问型操作
      • 1.1.2 加工型操作
    • 1.2 线性表的顺序存储结构
      • 1.2.1 定义顺序表数据类型方法1
      • 1.2.2 定义顺序表数据类型方法2
    • 1.3 顺序表的基本操作实现
      • 1.3.1 顺序表的初始化操作
      • 1.3.2 顺序表的插入操作
      • 1.3.3 顺序表的删除操作
      • 1.3.4 顺序表的更新操作
      • 1.3.5 顺序表的定位操作
      • 1.3.6 顺序表的遍历操作
      • 1.3.7 顺序表的创建操作

1. 线性表

具有1:1的线性关系的数据对象称为线性表。

1.1 线性表的定义

线性表是最简单的一种线性结构,具有如下特征。
(1)线性表中必存在唯一的一个“第一元素”。
(2)线性表中必须存在唯一的一个“最后元素”。
(3)除了最后元素之外,其余元素均有唯一的直接后继。
(4)除了第一个元素之外,其余元素均有唯一的直接前驱。

线性表的抽象数据类型定义形式:

ADT List
{ 数据对象:
D={ai | ai∈ElemSet,i=1,2,…,n>=0}
{ n为线性表的表长,即数据元素的个数;n=0时的线性表为空表。}
数据关系:
R ={ <ai-1,ai> |ai-1,ai∈D, i=2,3,…,n }
{ 设线性表为(a1,a2,…,ai,…,an),称i为ai在线性表中的位序}
基础操作:
初始化操作
销毁操作
访问型操作
加工型操作
} ADT List

&L表示会引起线表的变化,L表示不会引起线标的变化。

下面分别介绍线性表的各个基本操作的初始条件和实现的功能

1.1.1 访问型操作

这类操作只是访问线性表中的元素,并没有改变线性表。
(1)判断线性表是否为空:ListEmpty(L)。
初始条件:线性表L存在。
操作结果:若L为空表,则返回TRUE,否则返回FALSE。
(2)求线性表的长度:ListLength(L)
初始条件:线性表存在。
操作结果:放回L中的数据元素的个数。
(3)得到线性表中某个位置上的元素:GetElem(L,i,&e)。
初始化条件:线性表L已存在,且 1<=i<=LengthList(L)。
操作结果:用e返回L中第i个元素的值。
(4)通知比较,寻找位置:LocateElem(L,e,compare())。
初始条件:线性表L已存在,e为给定值,compare()是元素比较函数。
操作条件:返回L中第1个与e满足关系compare()的元素的位序。若这样的元素不存在,则返回值-1 。
(5)遍历线性表:ListTraverse(L)。
初始条件:线性表L已存在。
操作结果:依次访问L中的每个元素。

1.1.2 加工型操作

这类操作改变了原有的线性表。
(1)初始化操作:InitList(&L)。
操作结果:构造一个空的线性表L。
(2)销毁操作:DestroyList(&L)。
初始条件:线性表L已存在。
操作结果:销毁线性表L。
(3)线性表置空:CleaerList(&L)。
初始化条件:线性表L已存在。
操作结果:将L重置为空表,L由非空为空。
(4)修改线性表中某个位置上的元素置:PutElem(&L,i,e)。
初始化条件:线性表L已存在,且1<=i<=LengthList(L)。
操作结果:给L中第i个元素赋值e。L中的第i个元素的值发生了改变。
(5)在第i个位置上插入数据元素:ListInsert(&L,i,e)。
初始条件:线性表L已存在,且1<=i<=LengthList(L)+1.
操作结果:在L的第i个元素之前插入新的元素e,并将L的长度增1 。
(6)将线性表的第i个元素删除:ListDelete(&L,i,e)。
初始条件:线性表L已存在,且1<=i<=LengthList(L)。
操作结果:删除L的第i个元素,并且用e 返回其值,同时将L的长度减1 。

其中最重要的是插入操作和删除操作。

1.2 线性表的顺序存储结构

线性表的顺序存储结构是用一组连续的存储空间存放线性表中的各个数据元素,并用位置相邻的存储空间关系表示线性表中数据元素的直接前驱和直接后继的次序关系,称为顺序表。

1.2.1 定义顺序表数据类型方法1

包括以下数据成员:
(1)一片连续的存储空间(数组用于存放数据元素)。
(2)线性表的容量(数组的大小防止溢出)。
(3)线性表的长度(已经存入到数组中的数据元素个数)。

1.2.2 定义顺序表数据类型方法2

包括以下数据成员:
(1)一片连续的存储空间的起始地址(存放数组的起始地址)。
(2)线性表的容量(数组的大小防止溢出)。
(3)线性表的长度(已经存入到数组中的数据元素个数)。

对于两种存储结构的不同描述。第一种容易理解,使用相对简单,但是数组是顺序表的成员,大小固定,因此缺乏灵活性。第二种理解起来有一定难度,数组不是顺序表的成员,可根据实际问题的需要吗,在初始化操作中自定义数组的大小,因此具有较好的灵活性。

1.3 顺序表的基本操作实现

为了使数据结构中的操作具有很好的健壮性,在函数的定义中,通常用函数值表示操作的成功与失败。函数值为1,表示成功;函数值为0,表示失败。有时候为了方便起见,也可以将操作的结果作为函数的返回值。

1.3.1 顺序表的初始化操作

顺序表的初始化操作是完成一片连续空间的申请,将空间的起始地址、容量大小和数据个数0依次存放到顺序表中对应成员中。
算法的实现:

int initSqList(SqList* L, int max)
{
	L->data = (STD*)malloc(max * sizeof(STD));
	if (L->data == NULL)
	{
		perror("initSqList::");
		exit(0);
	}
	L->length = 0;
	L->listSize = max;
	return 1;//表示初始化操作成功
}

函数exit(0)的功能是结束程序的执行。为什么当动态申请存储空间失败时不用“return 0;”,而是调用函数exit(0)?原因是既然顺序表的初始化失败了,其他的有关对顺序表的操作都不可能正确执行,因此退出程序,并放回到系统。
【算法分析】
该算法不涉及基本操作的循环执行,算法的时间复杂度为T(n) = O(1)。

1.3.2 顺序表的插入操作

顺序表的插入操作是将某个学生数据插入顺序表中指针成员指向数组的给定位置,并将顺序表的长度成员加1
算法实现如下:

int insertSqList(SqList* L, int i, STD x)//i是插入位置,对应下标是i-1
{
	//插入失败的情况判断
	if (i<1 || i>L->length + 1)
	{
		printf("插入位置异常!\n");
		return 0;
	}
	if (L->length >= L->listSize)
	{
		printf("容量不够!\n");
		return 0;
	}
	//将区间[i-1,L->lenght-1]内的一组数据元素向后移动一个位置
	for (int k = L->length - 1; k >= i - 1; k--)
	{
		L->data[k + 1] = L->data[k];
	}
	//将待插入数据放入指定位置i,即下标i-1上
	L->data[i - 1] = x;
	//长度加1
	L->length++;
	//插入成功
	return 1;
}

寻找插入位置,将数据插进来,需移动数据元素。
最好情况(i=n+1);基本语句执行0次,时间复杂度为O(1);
最坏情况(i=1);基本语句执行n次,时间复杂度为O(n);
平均情况(1<=i<=n+1):等概率pi =1/(n+1)。
在这里插入图片描述
算法的时间复杂度为T(n)=O(n) 。

1.3.3 顺序表的删除操作

顺序表的删除操作是将顺序表中指针成员指向数组的给定位置的数组元素删除,并将数据个数减1.
算法实现如下:

int deleteSqList(SqList* L, int i, STD* x)
//i表示接受删除数据元素位置的整形变量
//x是将被删除的数据元素存回到主调函数中某个变量的指针变量
{
	//判断删除失败的条件是否成立
	if (L->length == 0)
	{
		printf("没有数据,不能删除!\n");
		return 0;
	}
	if (i <= 0 || i > L->length)
	{
		printf("位置异常,不能被删除\n");
		return 0;
	}
	//将被删除的数据元素存放到*x中
	*x = L->data[i - 1];
	//将区间[i,L->length-1]内的一组数据元素向前移动一个位置
	for (int k = i; k < L->length; k++)
	{
		L->data[k - 1] = L->data[k];
	}
	//长度减1
	L->length--;
	//删除成功
	return 1;
}

【算法分析】
寻找删除位置,将数据删除,需移动数据元素。
最好情况(i=n+1);基本语句执行0次,时间复杂度为O(1);
最坏情况(i=1);基本语句执行n次,时间复杂度为O(n);
平均情况(1<=i<=n):等概率pi =1/(n)。
在这里插入图片描述
算法的时间复杂度为T(n)=O(n) 。

1.3.4 顺序表的更新操作

顺序表的更新操作是用新数据替换指定位置的数据。

int updateSqList(SqList* L, int i, STD x)
{
	//更新失败条件的判断
	if (L->length == 0)
	{
		printf("没有数据,不能更新!\n");
		return 0;
	}
	if (i<1 || i>L->length)
	{
		printf("位置不合适!\n");
		return 0;
	}
	//开始更新数据
	L->data[i - 1] = x;
	//更新成功
	return 1;
}

【算法分析】
该算法的操作不涉及循环,均为顺序执行,所以算法的时间复杂度为T(n)=O(1)。

1.3.5 顺序表的定位操作

顺序表的定位操作是根据给定的条件得到某个数据元素的位置。定位操作又称为查找操作。
位置从1开始
算法实现如下:

int locationSqList(SqList* L, char* newid)
{
	int i;
	//查找失败的条件判断
	if (L->length == 0)
	{
		printf("没有数据!\n");
		return 0;
	}
	for (int i = 0; i < L->length; i++)
	{
		//查找成功的条件的判断
		if (strcmp(L->data[i].name, newid) == 0)
		{
			return i + 1;
		}
	}
	//查找失败
	return 0;
}

【算法分析】
按照给定的条件,查找相应的数据元素,需逐个判断。最好的情况是O(1);最坏的情况是O(n)。
等概率加权平均是O(n)。

1.3.6 顺序表的遍历操作

顺序表的遍历操作是输出顺序表中存放的所有数据元素。
分析:遍历操作不会引起顺序表的变化,遍历函数只需一个形参
算法实现如下:

int dispSqlist(SqList* L)
{
	if (L->length == 0)
	{
		printf("没有数据!\n");
		return 0;
	}
	for (int i = 0; i < L->length; i++)
	{
		printf("%10s%7.2f\n", L->data[i].name, L->data[i].score);
	}
	return 1;
}

【算法分析】
显示所有的数据,必须逐个依序显示,时间复杂度为T(n)=O(n)。

1.3.7 顺序表的创建操作

顺序表的创建操作依序存入顺序表中。
一共有两种算法:
算法1:调用初始化函数和插入函数创建顺序表

void createSqList1(SqList* L, int maxsize)
{
	int n = 0;
	STD x;
	char yn;

	//调用初始化函数,创建空表——申请空间来存储表的数据
	do
	{
		printf("请输入第%d个学生的姓名和分数,用空格隔开:", n + 1);
		scanf("%s%f", x.name, &x.score);
		//空度回车,以便下次正确读入数据
		getchar();
		//调用插入函数,将数据插入到尾部
		insertSqList(L, ++n, x);

		printf("继续输入吗?Y/N\n");
		scanf("%c", &yn);
	} while (yn == 'Y' || yn == 'y');
}

算法2:直接读取数据来创建顺序表

void createSqList2(SqList* L, int maxsize)
{
	int n=0;
	STD x;
	char yn;

	//初始化
	L->data = (STD*)malloc(maxsize * sizeof(STD));
	if (L->data == NULL)
	{
		perror("createSqList2::");
		return 0;
	}
	L->listSize = maxsize;
	L->length = 0;

	//读取数据并插入
	do
	{
		printf("请输入第%d个学生的姓名和分数,用空格隔开:", n + 1);
		scanf("%s%f", x.name, &x.score);
		//空度回车,以便下次正确读入数据
		getchar();
		L->data[n] = x;
		if (n >= L->listSize - 1)
		{
			break;
		}
		else
		{
			n++;
		}
		printf("继续输入吗?\n");
		scanf("%c", &yn);
	} while (yn == 'Y' || yn == 'y');
}

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

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

相关文章

Windows环境下使用Pycharm运行sh文件

博主在调试一些程序时&#xff0c;时常遇到 .sh文件&#xff0c;这是Linux中的shell脚本文件&#xff0c;那么这种文件在windows下如何运行呢&#xff0c;其实我们可以通过git来实现&#xff0c;接下来看我操作。 首先我们需要安装Git&#xff0c;关于其安装过程可以参考博主这…

wholeaked:一款能够追责数据泄露的文件共享工具

关于wholeaked wholeaked是一款功能强大的文件共享工具&#xff0c;该工具基于go语言开发&#xff0c;可以帮助广大系统管理员和安全研究人员在组织发生数据泄露的时候&#xff0c;迅速找出数据泄露的“始作俑者”。 wholeaked可以获取被共享的文件信息以及接收人列表&#x…

【云计算自学路线】

云计算包含的技术内容和涉及的方向比较多&#xff0c;一定要进行系统化的学习才能更好的掌握这门技术。 云计算作为互联网新技术领域&#xff0c;现阶段也是出于高速发展期&#xff0c;想学习加入云计算行业的小伙伴可以抓紧机会了&#xff0c;跟着小课一起来了解云计算以及它…

【PTA Advanced】1146 Topological Order(C++)

目录 题目 Input Specification: Output Specification: Sample Input: Sample Output: 思路 C 知识UP 代码 题目 This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topological order obtained from the given dire…

佳能镜头EOS系统EF协议逆向工程(四)常用指令

目录 EOS5000&#xff08;基础协议&#xff09; AE*记忆键 物镜38-76焦距76mm的帧值&#xff08;手动焦距&#xff09; 帧操作和解码命令 指令0x0A:请求物镜可用 指令0xA0、B0、B2、90和F0&#xff1a;光学特性和AF状态 指令0x80-0A:请求物镜的物理特性 指令0xC2&#…

(考研湖科大教书匠计算机网络)第四章网络层-第四节:IP数据报的发送和转发过程

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;概述二&#xff1a;举例三&#xff1a;路由器可以隔离广播域本节对应视频如下 【计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;】&…

文华财经期货策略高胜率顶底反转指标公式,短线操盘量化CTA主图K线指标

​期货指标公式不是交易的圣杯&#xff0c;也不是期货亏损后的救命稻草。请理性运用指标公式&#xff0c;独立决策&#xff0c;盈亏自负。 什么是多头趋势行情&#xff1f; 多头趋势行情指的是市场单边多头行情。具体表现为上涨过程中出现连续上涨的高点与低点&#xff0c;只要…

3.4 ISIS和OSPF之间路由引入

实验目的掌握在IS-IS中引入OSPF路由的方法掌握在OSPF中引入IS-IS路由的方法实验拓扑ISIS和OSPF之间路由引入实验拓扑如图3-3所示: 图3-3:ISIS和OSPF之间路由引入 实验步骤IP地址的配置R1的配置 <Huawei>system-view [Huawei]undo info-center enable

Spring 框架源码(六) Bean的生命周期全流程源码解析

Spring框架作为Java王国的地基&#xff0c;我觉得它包含了很多精妙的设计&#xff0c;例如Bean工厂设计、Bean的生命周期、tx、aop、web、mvc等&#xff0c;最核心基本的Bean设计是Spring 的框架的灵魂&#xff0c;本文就Bean的生命周期全流程做源码程度上的解析&#xff0c;欢…

【surfaceflinger源码分析】surfaceflinger进程的消息驱动模型(二)

接着上篇文章中的两个新疑问: mEventTube是个什么玩意&#xff1f;MessageQueue::setEventConnection(…) 什么时候有谁调用的 &#xff1f; BitTube mEventTube的类型为class BitTube&#xff0c;BitTube从字面上的意思来看bit管道&#xff0c;bit隧道&#xff0c;应该是一…

20230216在Ubuntu18.04下查看硬盘信息

20230216在Ubuntu18.04下查看硬盘信息 2023/2/16 22:25 百度搜索&#xff1a;查看 HDD 缓存 ubuntu [BEGIN] 2023/2/16 22:10:24 rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ rootrootrootroot-X99-Turbo:~$ cat /sys/block/sda/device/modelHUS726060ALE61…

VIVADO2022 sdk 工程创建流程

正点原子uart历程复现 create block design&#xff08;起名 为System&#xff09; -> open block design -> 号/IP catalog 中搜索zynq 双击打开&#xff0c; 将和pl相关的时钟都干掉 再auto 布线一下 把herarchy中的sources 中的system.bd右键、 无脑下一步导出 如…

赛狐ERP|亚马逊产品缺货怎么办?该如何补救?

由于物流时效的延长&#xff0c;运输成本的增加&#xff0c;亚马逊的仓储限制等各种原因&#xff0c;断货问题很常成为亚马逊卖家的普遍困扰。那么亚马逊产品缺货应该怎么办&#xff01;1、提高产品价格&#xff1a;除了卖自己的Listing此外&#xff0c;提高产品价格也是一种保…

基于微信小程序的智能招聘小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

Cygwin安装与Mingw

共同点&#xff1a;window下编译环境 区别&#xff1a;cygwin(gnu windows)模拟Linux编译环境&#xff0c; mingw模拟window编译环境&#xff0c;生成.exe可执行文件 目录 Cygwin安装 一、官网下载 二、双击安装 三、选择安装路径后&#xff0c;到连接方式如图 四、添加连…

USB3.0移动硬盘启动Win7的方法(AHCI/AMD USB3.0/Win7)

古董电脑(intel处理器&#xff0c;无USB3.0接口)突然坏了&#xff0c;已经没有维修价值了&#xff0c;硬盘还是完好的。欲把硬盘拆下来&#xff0c;装到USB3.0硬盘盒上&#xff0c;然后在新电脑(AMD R5-4650G/A520)上从USB3.0硬盘盒上启动。 一、需要工具 SATA数据线PS/2鼠标…

合并两个有序数组-力扣88-java

一、题目描述给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。注意&#xff1a;最终&#xff0c;合…

【mac】在m2 mbp上通过Parallels Desktop安装ubuntu22.04

文章目录前言一、参考文章二、版本信息三、方法1:通过ubuntu官网提供的iso安装3.1 配置服务器3.2 安装图形界面四、方法2:通过Parallels Desktop提供的安装包五、 小工具5.1 调整应用栏图标大小5.2 ubuntu获取mac的剪切板5.3 调整terminal字体大小5.4 安装samba5.5 ubuntu连接m…

【Java基础】022 -- Lambda与递归练习

目录 一、Lambda表达式 1、Lambda初体验 2、函数式编程 3、Lambda表达式的标准格式 4、小结 5、Lambda表达式的省略写法 ①、示例代码 ②、小结 6、Lambda表达式的练习 ①、Lambda表达式简化Comparator接口的匿名形式 二、综合练习 1、按照要求进行排序&#xff08…

四【Spring框架】

目录一 Spring概述二 .Spring 的体系结构三 Spring的开发环境3.1 配置pom.xml文件四 项目案例&#xff1a;4.1 创建实体类4.2 在pom.xml中引入依赖4.3 配置Spring-config.xml文件4.4 Test✅作者简介&#xff1a;Java-小白后端开发者 &#x1f96d;公认外号&#xff1a;球场上的…