第25讲:顺序表专题

1.什么是数据结构

2.顺序表概念及结构

3.顺序表分类

4.实现动态顺序表

1.什么是数据结构

数据结构是计算机存储、组织数据的方式。可以用来完成通讯录项目。

2.顺序表概念及结构

2.1线性表

线性表是n个具有相同特性的数据元素的有限序列

常见的线性表:顺序表,链表,栈队列,字符串

线性表在逻辑上是线性的,但在物理结构上却不一定,也就是在内存上的存储不一定是连续的

3.顺序表分类

静态顺序表:空间是固定的,给多了浪费空间,给少了空间不够

缺点多,不建议使用

动态顺序表:空间可以扩大,但扩大空间会浪费时间

相较于静态顺序表优点多,建议使用

4.实现动态顺序表

文件名:SeqList.c

#define _CRT_SECURE_NO_WARNINGS
#include "Seqlist.h"
void initSeqList(SL* pSL)//初始化顺序表
{
	pSL->pa = NULL;
	pSL->size = 0;
	pSL->capacity = 0;
}

void cheak(SL* psl1)//检查空间是否足够
{
	if (psl1->size == psl1->capacity)
		expandSL(psl1);
}

void expandSL(SL* pSL)//扩容
{
	int newcapacity = pSL->capacity == 0 ? 4 : 2 * pSL->capacity;
	SLdatatype* pSLm = realloc(pSL->pa, (size_t)newcapacity * sizeof * (pSL->pa));
	if (pSLm == NULL)
	{
		perror("relloc");
		exit(1);
	}
	else
		pSL->pa = pSLm;
	pSL->capacity = newcapacity;
}

void printSL(SL* pSL)//打印顺序表
{
	assert(pSL);
	int i;
	for (i = 0; i < pSL->size; i++)
		printf("%d ", pSL->pa[i]);
}

void backaddSL(SL* pSL, SLdatatype n)//后增
{
	assert(pSL);
	cheak(pSL);
	pSL->pa[pSL->size++] = n;
}

void frontaddSL(SL* pSL, SLdatatype n)//前增
{
	assert(pSL);
	cheak(pSL);
	int i;
	for (i = 0; i < pSL->size; i++)
	{
		pSL->pa[pSL->size - i] = pSL->pa[pSL->size - i - 1];
	}
	pSL->pa[0] = n;
	pSL->size++;
}

void backdel(SL* pSL)//后删
{
	assert(pSL != NULL);
	assert(pSL->size > 0);
	pSL->size--;
}

void frontdel(SL* pSL)//前删
{
	assert(pSL != NULL);
	assert(pSL->size > 0);
	int i;
	for (i = 0; i < pSL->size - 1; i++)
	{
		pSL->pa[i] = pSL->pa[i + 1];
	}
	pSL->size--;
}

void posaddSL(SL* pSL, SLdatatype n, int pos)//指定位置插入
{
	assert(pSL);
	int i = 0;
	for (i = 0; i < pSL->size - pos + 1; i++)
	{
		pSL->pa[pSL->size - i] = pSL->pa[pSL->size - i - 1];
	}
	pSL->pa[pos - 1] = n;
	pSL->size++;
}

void posdelSL(SL* pSL, int pos)//指定位置删除
{
	assert(pSL);
	int i = 0;
	for (i = 0; i < pSL->size - pos + 1; i++)
	{
		pSL->pa[pos - 1 + i] = pSL->pa[pos + i];
	}
	pSL->size--;
}

void SLfind(SL* pSL, int n)//元素查找
{
	int i = 0, flag = 1;
	for (i = 0; i < pSL->size; i++)
	{
		if (pSL->pa[i] == n)
		{
			printf("元素下标为%d\n", i);
			flag = 0;
		}
	}
	if (flag)
		puts("没有该元素");
}

void SLalter(SL* pSL, int n, int pos)//元素修改
{
	pSL->pa[pos - 1] = n;
}

void SLdesdroy(SL* pSL)//销毁
{
	assert(pSL);
	if (pSL->pa != NULL)
	{
		free(pSL->pa);
		pSL->pa = NULL;
	}
	pSL->size = 0;
	pSL->capacity = 0;
}

文件名:SeqList.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int SLdatatype;
typedef struct SeqList
{
	SLdatatype* pa;//数组首元素地址
	int size;//元素个数
	int capacity;//数组容量
}SL;

//初始化顺序表
void initSeqList(SL* pSL);

//判断空间是否足够
void cheak(SL* psl1);

//扩容
void expandSL(SL* pSL);

//打印顺序表
void printSL(SL* pSL);

//后增
void backaddSL(SL* pSL, SLdatatype n);

//前增
void frontaddSL(SL* pSL, SLdatatype n);

//后删
void backdel(SL* pSL);

//前删
void frontdel(SL* pSL);

//指定位置插入
void posaddSL(SL* pSL, SLdatatype n, int pos);

//指定位置删除
void posdelSL(SL* pSL, int pos);

//元素查找
void SLfind(SL* pSL, int n);

//元素修改
void SLalter(SL* pSL, int n, int pos);

//销毁
void SLdesdroy(SL* pSL);

文件名:test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Seqlist.h"
void test1(SL* psl1)//测试后增
{

	backaddSL(psl1, 5);
	backaddSL(psl1, 6);
	backaddSL(psl1, 7);
	printSL(psl1);
}
void test2(SL* psl1)//测试前增
{
	frontaddSL(psl1, 5);
	frontaddSL(psl1, 6);
	frontaddSL(psl1, 7);
	frontaddSL(psl1, 8);
	frontaddSL(psl1, 9);
	frontaddSL(psl1, 5);
	frontaddSL(psl1, 6);
	printSL(psl1);
	putchar('\n');
}
void test3(SL* psl1)//测试后删
{
	backdel(psl1);
	printSL(psl1);
}
void test4(SL* psl1)//测试前删
{
	frontdel(psl1);
	printSL(psl1);
}
void test5(SL* psl1)//测试指定位置插入
{
	posaddSL(psl1, 80, 3);
	printSL(psl1);
}
void test6(SL* psl1)//测试指定位置删除
{
	posdelSL(psl1, 3);
	printSL(psl1);
}
void test7(SL* psl1)//测试元素查找
{
	SLfind(psl1, 100);
}
void test8(SL* psl1)//测试元素修改
{
	SLalter(psl1, 100, 3);
	printSL(psl1);
}
void test9(SL* psl1)//测试销毁
{
	SLdesdroy(psl1);
	printSL(psl1);
}
int main()
{
	SL sl1;
	initSeqList(&sl1);
//	test1(&sl1);
	test2(&sl1);
//	test3(&sl1);
//	test4(&sl1);
//	test5(&sl1);
//	test6(&sl1);
//	test7(&sl1);
//	test8(&sl1);
	test9(&sl1);
	return 0;
}

第5行,将int重命名。

目的:若想替换代码中所有的int,可以改变第5行的int,做到一键替换

注意:capacity说明的是最多可以容纳多少个元素,不是空间的大小,单位不是字节

第六行:创建结构体存储数据

第8和第9行,通过首元素地址下标访问,可以访问到数组中的每一个元素,元素个数是为了方便访问的,体现在后面的代码实现中

第10行:设置界限,数元素个数等于数组容量,说明需要扩容,否则不能写入数据

第一步,顺序表的初始化,没什么好说的

数元素个数等于数组容量,说明需要扩容,否则不用

第18行:newcapacity说明扩容后是最多可以容纳多少个元素

现在的问题是:一次要开辟多少空间,开辟多了,那么开辟的次数就少了,可以节省时间,但浪费的空间较多。开辟少了,那么开辟的次数就多了,浪费时间,但是相对前一个可以节省时间。

所以,我们采取一个折中的办法,也是性价比较高的一个。那就是将空间扩大到原来的两倍。第一次开辟比较特殊,初始化后,空间是0,不能扩大到原来的两倍,因为0*2=0,也就是没扩大。所以,就有了第18行的写法。

第19行:要开辟的字节数应是一个元素的大小*开辟后最大元素个数

其余的写法参考动态内存管理,这里不再赘述

若传来的是空指针,会出现错误,所以,要用assert断言一下

第一步:assert防止空指针

第二步:检查空间够不够,不够就会扩容,保证在写入元素时空间大小足够

第三步:写入元素,写完后要让元素个数加一

第一步:断言

第二步:检查空间

第3步:让所有元素往后挪一格

最后:在前面写入元素,元素个数加一

第一步:断言防空指针

第二步:断言防止顺序表中没有数据

第三步:删除元素

问题:为什么这里元素个数减1就行了?

空间里会默认存随机数,所以我们无论给需删除的地方赋什么值都不合适

所以,我们只需要能正常使用就行了,假设那个元素被删除了就行了

问题:元素个数减1是不是必要的?

是的,不减会影响正常使用,体现的后面的代码中

第一步:双断言

第二步:让所有元素像前移动一格

第三步:元素个数减一

第一步:指定位置和后面的元素都向后移动一个

第二步:插入元素

第三步:元素个数加1

第一步:指定位置后面的元素往前移动一格

第二步:元素个数减一

第一步:一个一个比较,有相同的说明找到了,打印该元素的下标,使flag为0

第二步:没找到说明flag是1,打印“没找到”。

直接修改就行了,没什么好说的

第一步:assert断言

第二步:如果pa不指向NULL,说明pa是有分配空间的,free掉,并使pa指向NULL。

第三步:使元素个数和最大元素个数为0

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能监控系统EasyCVR设备录像无法下载是什么原因?该如何解决?

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…

【React教程】(2) React之JSX入门与列表渲染、条件渲染详细代码示例

目录 JSX环境配置基本语法规则在 JSX 中嵌入 JavaScript 表达式在 JavaScript 表达式中嵌入 JSXJSX 中的节点属性声明子节点JSX 自动阻止注入攻击在 JSX 中使用注释JSX 原理列表循环DOM Elements 列表渲染语法高亮 条件渲染示例1&#xff1a;示例2&#xff1a;示例3&#xff08…

递归方法的理解,什么时候递,什么时候归

简单总结一下递归。递归就是在运行的过程中调用自己。递归需要有一个出口&#xff0c;如果无限递归是没有意义的&#xff0c;而且递归到一定程度&#xff0c;程序就会由于栈内存溢出导致程序报错。 我们先来看段代码&#xff1a;建议大家先思考这个代码在控制台输出的结果是什…

性能测试+Jmeter介绍

文章目录 什么是性能测试?性能测试的目的性能测试分类一般性能测试负载测试压力测试大数据量测试配置测试稳定性测试 性能测试术语虚拟用户并发及并发用户数响应时间每秒事务数吞吐量、吞吐率点击率性能计数器资源利用率 性能测试流程测试计划阶段测试设计阶段测试开发阶段测试…

SQL中实现行列转换

目录 方法一&#xff1a;sum case when 方法二&#xff1a;sum if 方法三&#xff1a;pivot 现在有一张表class_gender&#xff0c;内容如下&#xff1a; classgender一年级女一年级女一年级男一年级男二年级女二年级女二年级男 现在我们要根据上表&#xff0c;统计得到下…

Redis常用数据结构与应用场景

常用数据结构 StringHashListSetZset String常用操作 String应用场景 Hash常用操作 hash应用场景 Hash结构优缺点 优点 同类数据归类整合存储,方便数据管理相比String操作消耗内存与spu更小相比string更节省空间 缺点 过期功能不能使用在field上,只用用在key上Redis集群…

java学习之路(2)-编译java文件运行Java文件

创建.java后缀文本文件HelloWorld .java 写入代码&#xff1a; public class HelloWorld { public static void main(String []args) { System.out.println("Hello World"); } } 运行cmd命令 找到代码所在目录 输入javac编译Java文件生成HelloWorld.class 编译:…

CentOS 7 部署 ZeroTier Moon 节点

ZeroTier是一套使用UDP协议构建的SD-WAN网络软件&#xff0c;其主要有三部分组成&#xff1a;行星服务器Planet、月亮服务器Moon、客户端节点LEFA&#xff0c;行星服务器是ZeroTier的根节点&#xff0c;可以采用ZeroTier官方的服务器&#xff0c;也可以使用开源代码自行搭建 月…

Android中下载 HAXM 报错 Intel® HAXM installation failed,如何解决?

最近在搭建 Flutter 环境&#xff0c;但是在 Android Studio 中安装 Virtual Device 时&#xff0c;出现了一个 问题 Intel HAXM installation failed. To install Intel HAXM follow the instructions found at: https://github.com/intel/haxm/wiki/Installation-Instructio…

深度强化学习(王树森)笔记09

深度强化学习&#xff08;DRL&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。本文在ChatGPT辅助下完成。 参考链接 Deep Reinforcement Learning官方链接&#xff1a;https://github.com/wangshusen/DRL 源代码链接&#xff1a;https://github.c…

【Servlet】Smart Tomcat插件简化Servlet开发流程及解决常见问题

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【Servlet】 本专栏旨在分享学习Servlet的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 一、Smart Tomcat插件二…

【2023地理设计组一等奖】基于GIS的桥梁隧道三维建模与可视化

作品介绍 1 设计背景和意义 随着我国基础建设规模不断扩大和深入,构建桥梁可视化管理模型,全面推动智慧桥梁,已成为现代隧道桥梁建设行业的发展趋势。传统的桥梁建模工作需要复杂的算法设计并需要熟练编程实践技能,实现周期长。开发自主知识版权的桥梁建模软件系统或专用插…

时间复杂度解释

时空复杂度概述 首先o(1), o(n), o(logn), o(nlogn)是用来表示对应算法的时间复杂度,这是算法的时间复杂度的表示。不仅仅用于表示时间复杂度&#xff0c;也用于表示空间复杂度。 算法复杂度分为时间复杂度和空间复杂度。其作用&#xff1a; 时间复杂度是指执行这个算法所需要…

Keepalived + DR 集群

目录 1、Keepalive VRRP 说明 故障切换 工作原理 核心组件 2、Keepalived DR 集群 拓扑规划 前期准备 配置 Httpd 服务 配置 Nginx 服务 配置 LVS 主 node_01 配置 LVS 从 node_02 测试 LVS 集群 测试主备切换 3、Keepalived 脑裂现象 4、Keepalived 心态检测 …

C++字符串的常用操作函数全总结

文章目录 1.string、string.h和cstring的区别2.字符串定义3.求字符串的长度&#xff08;也可以求array对象长度&#xff09;4.输入字符串5.分割截取字符串4.在字符串中查找指定子字符串,并返回其第一次出现的位置5.替换字符串中的一部分6.在字符串指定位置插入字符串7.复制字符…

【漏洞通告】 Jenkins CLI 任意文件读取漏洞

漏洞概况 Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件项目可以进行持续集成。Jenkins 有一个内置的命令行界面&#xff08;CLI&#xff09;&…

安装elasticsearch、kibana、IK分词器

1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net 1.2.加载镜像 这里我们采用elasticsearch的7.12.1版本的镜像&#xff0c;这个镜像体积非常大&#xff0…

在Spring Boot中使用iTextPDF创建动态PDF文档

最近&#xff0c;我们的系统新增了一个客服模块&#xff0c;其中一个重要功能是能够以PDF格式导出客服与用户之间的聊天记录。这些聊天记录包含文字、图片和文件等多种内容。为了实现这一功能&#xff0c;我们首先使用了itextpdf 5.x版本制作了一个Demo。今天&#xff0c;我将与…

kubernetes-快速部署一套k8s集群

1、前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式&#xff1a; kubeadm Kubeadm是一个K8s部署工具&#xff0c;提供kubeadm init和kubeadm join&#xff0c;用于快速部署Kubernetes集群。 二进制包 从github下载发行…

力扣题目训练(5)

2024年1月29日力扣题目训练 2024年1月29日力扣题目训练345. 反转字符串中的元音字母349. 两个数组的交集350. 两个数组的交集 II96. 不同的二叉搜索树97. 交错字符串44. 通配符匹配 2024年1月29日力扣题目训练 2024年1月29日第五天编程训练&#xff0c;今天主要是进行一些题训…