【c语言】数据结构-顺序表

news2024/11/15 12:22:44

主页:114514的代码大冒险

qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ )

Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com

文章目录

目录

文章目录

前言

一、顺序表是什么?

二、项目功能的逐一实现(基本)

1. 准备工作

2.打印(SeqListPrint)和初始化(SeqListInit)

1.头插(对顺序表首部进行内容的增加)

2.头删(对顺序表首部进行内容的删除)

3.尾插(对顺序表尾部进行内容的增加)

4.尾删(对顺序表尾部进行内容的删除)

5.内容扩增:

6.销毁顺序表(动态内存的释放)

三,补充功能(调整)

1.随机插入(对指定位置增加内容)

2.随机删除(对指定内容进行删除)

总结


前言

数据结构是一种计算机科学技术领域广泛使用的专业术语,在很多书籍以及博客中,对数据结构的解释为数据在计算机的存储方式,很容易让人误以为数据结构只是一种数据的物理存储方式,其实不然,数据结构可以理解为:数据 + 结构数据是描述客观事物的符号,为程序操控,存储在计算机上,结构包括数据的逻辑结构和存储结构。

因此足以见得数据结构在计算机领域的重要作用。


 

一、顺序表是什么?

区别于链表,顺序表支持随机访问,从而支持二分查找,冒泡排序等需按下标进行访问的算法

顺序表其实就是数组,本文将主要介绍顺序表的增删查改操作

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致 N 定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

二、项目功能的逐一实现(基本)

1. 准备工作

我们按照三子棋和通讯录的标准工程旧历,创立三个文件 SeqList.c(实现各种功能接口(函数))  SeqList.h(存放此次需要的头文件以及函数声明) test.c(调用函数,测试功能是否正常)。

 另外还要介绍一下顺序表的组成:

 

2.打印(SeqListPrint)和初始化(SeqListInit)

SeqList.h:

 SeqList.h:

void SeqListPrint(SL* ps)
{
	for (int i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}
void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = ps->capacity = 0;


}

test.c:

因为会涉及多次测试,所以我们将测试函数分成多个:

 

 

 为什么使用这么长的命名?
因为这和c++的stl库相关联,方便日后学习c++。

1.头插(对顺序表首部进行内容的增加)

代码:

void SeqListPushFront(SL* ps, SLDataType x)
{
	SeqListCheckCapacity(ps);//扩容函数,在插入内容之前进行容量的检查
                             //避免出现访问错误

	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
		 
	}
	ps->a[0] = x;
	ps->size++;
}

思想:将最后一个元素后移,然后倒数第二个数移到倒数第一个数,以此类推,全部移动之后,

将要添加的值放在头一个位置上:
 

2.头删(对顺序表首部进行内容的删除)

代码:

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);
	int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

思想:就是将第二个位置上的数字放在第一个位置上,第三个位置上的数字放在第二个位置上,以此类推  全部移动之后,再将记录数据个数的size进行-1操作;

3.尾插(对顺序表尾部进行内容的增加)

代码:

void SeqListPushBack(SL* ps, SLDataType x)
{

	SeqListCheckCapacity(ps);//检查顺序表容量,容量不足进行扩容

	ps->a[ps->size] = x;
	ps->size++;
}

思想:在已有数据的末尾位置放置一个新数据。

4.尾删(对顺序表尾部进行内容的删除)

代码:

void SeqlistPopBack(SL* ps)
{

	

	assert(ps->size > 0);
	
	ps->size--;

}

注意:
一定在进行删除之前,检查数据现存个数,避免出现非法访问,

这里如果你不检查,可能当时编译器不会报错,但是,在释放内存时,就会出现问题

5.内容扩增:

代码:

void SeqListCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newcapacity;
	}

}

为什么进行内容扩增?

 扩容为什么一次扩容增加为之前的二倍?

因为一次扩容扩多了,空间浪费;扩少了,需多次进行扩容操作。

二倍则是一个比较友好的扩容选择。

注意:这里的扩容,有可能要扩大的容量本身为0;而0*2 = 0,所以我们选择进行一个判断

如果为0,我们就将容量扩大到4;如果不为零,我们就按照扩为二倍处理

6.销毁顺序表(动态内存的释放)

代码:

void SeqListDestory(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

三,补充功能(调整)

1.随机插入(对指定位置增加内容)

代码:

void SeqListInsert(SL* ps, int pos, SLDataType x)
{
	// 温柔的处理方式
	/*if (pos > ps->size || pos < 0)
	{
		printf("pos invalid\n");
		return;
	}*/
	//比较粗暴的方式
	assert(pos >= 0 && ps->size);
	
	SeqListCheckCapacity(ps);

	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}

	ps->a[pos] = x;
	ps->size++;
}

思想:

以插入位置2举例:

 

注意:

这里要对插入位置pos进行检查(检查方法分为if语句与assert语句),避免非法访问


于是便有了对头插,尾插的改动:
 

SeqListInsert(ps, ps->size, x);//尾插

 

SeqListInsert(ps, 0, x);//尾插

2.随机删除(对指定内容进行删除)

删除之前,要找到目标数据的下标:
 

int SeqListFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}

	return -1;
}

然后就是正题:

void SeqListErase(SL* ps, int pos)
{
	assert(pos >= 0 && pos < ps->size);

	int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	}
	ps->size--;
}

于是便有了对头删,尾删的改动

SeqListErase(ps, 0);//头删
SeqListErase(ps, ps->size - 1);//尾删

总结

这就是本次全部内容了,顺序表是在数据结构中打的第一枪,虽然在整个数据结构的学习中并不算难,但是依然要认真起来,加油O(∩_∩)O哈哈~

 

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

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

相关文章

Python-Flask-2023.1.22

1、WSGIweb server gateway interface一个框架定义的简单通用的接口Web服务器网关接口&#xff08;Python Web Server Gateway Interface&#xff0c;缩写为WSGI&#xff09;是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。flask框架内有默认的…

手写vue及源码解析一 rollup环境的搭建

开篇 都手写源码了&#xff0c;那就顺便分析一下源码吧。 rollup环境的搭建 作为了解就行。需要使用rollup来编译我们自己手写的vue代码。 需要安装rollup,rollup的babel插件&#xff0c;以及babel核心和babel预设&#xff08;可以理解为初始化模板&#xff09;。 mkdir vu…

Java变量定义时候的注意事项

常量定义的基本注意事项 在JAVA语言中&#xff0c;主要利用final关键字&#xff0c;&#xff08;在Java类中灵活使用static关键字&#xff09;来定义常量。 当常量被设定后&#xff0c;一般情况下就不允许在进行更改了&#xff0c;如可以利用以下的形式来定义常量&#xff1a;…

仿写Dubbo-Java Socket

概念 socket 被翻译为“套接字”&#xff0c;socket是计算机之间进行通信的一种方式。通过socket可以实现端(端口)到端通信。Java的java.net包中提供了进行socket通信的类。主要使用ServerSocket和Socket类实现通信。 ServerSocket 服务端应用使用java.net.ServerSocket类来获取…

Node.js 操作MongoDB (Mongoose) 数据库

在讲Node.js通过使用mongoose模块来操作MongoDB数据库之前首先是关于MongoDB数据库的安装和MongoDB服务以及对MongoDB命令行的操作和可视化工具MongoDBCompass的一个基本使用&#xff1b;那么在这里已经准备好了关于MongoDB数据库的内容了&#xff1a; MongoDB数据库安装详细 &…

学习shell与shell编程

Linux配置文件都是以ASCII的纯文本形式存在。 为什么学习vi 1)UnixLike系统都会内置vi文本编辑器&#xff0c;其他的文本编辑器则不一定存在 2)许多软件的编辑接口都会主动调用vi 3)vi具有程序编辑的能力&#xff0c;可以主动以字体颜色辨别语法的正确性 4)程序简单&#…

06-jquery函数

2.6函数 .6.1第一组函数 1 val():操作dom函数的value值 val()&#xff1a;没有参数&#xff0c;获取dom数组中第一个dom对象的value值。 val(参数)&#xff1a;有参数&#xff0c;给dom数组中所有dom对象的value属性赋值。 2 text()&#xff1a;操作标签文本内容&#xff0c;…

springCloud集成elk+filebeat+kafka+zipkin实现多个服务日志链路追踪聚合到es

一、目的 如今2023了&#xff0c;大多数javaweb架构都是springboot微服务&#xff0c;一个前端功能请求后台可能是多个不同的服务共同协做完成的。例如用户下单功能&#xff0c;js转发到后台网关gateway服务&#xff0c;然后到鉴权spring-sercurity服务&#xff0c;然后到业务…

【实操案例十一】使用try-except手动捕获异常 实例代码及运行效果图!

任务一&#xff1a; 编写程序输入学员成绩 异常捕获忘了的同学&#xff0c;可以参考这个&#xff1a;Bug的常见类型及异常处理机制 # 任务一&#xff1a; 编写程序输入学员成绩iint(input(请输入学员成绩&#xff1a;)) if 0<i<100:print(i) else:raise Exception(分数…

产品设计-基础控件-信息输入控件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 产品设计-基础控件-信息输入控件1.1.文本框一、1.1.11.1.2、占位符文本1.1.3 输入框1.1.4 帮助文本1.1.5 初始默认值1.1.6 输入文本1.1.7 跟踪图标1.1.8 格式化标记1.2 单选按…

java枚举类2023028

一个类的对象是有限而且固定的&#xff0c;比如季节类&#xff0c; 它只有4个对象&#xff1b;再比如行星类&#xff0c;目前只有8个对象。这种实例有限而且固定的类&#xff0c;在Java里被称为枚举类。在早期代码中&#xff0c;可能会直接使用简单的静态常量来表示枚&#xff…

设计模式 - 六大设计原则之OCP(开闭原则)

文章目录概述Case接口定义接口实现Bad ImplBetter Impl概述 Open-Close Principle 在面向对象编程领域中&#xff0c;开闭原则规定软件中的类、对象、模块和函数对扩展应该是开放的&#xff0c;但对修改是封闭的。 这意味着 应该用抽象定义结构&#xff0c;用具体实现扩展细节…

使用 AJAX+JSON 实现用户查询/添加功能

实现用户查询/添加功能1. 查询功能准备selectAllServlet&#xff1a;brand.html&#xff1a;2. 添加功能addBrand.html&#xff1a;表单&#xff1a;<script&#xff1a;addServlet&#xff1a;1. 查询功能 需求&#xff1a;在onload&#xff08;页面加载完成&#xff09;事…

SSM项目实战【从 0 到 1】:个人博客

文章目录前言一、项目简介二、项目技术栈三、准备工作1、Spring Boot 项目创建2、mybatis 配置3、数据库创建四、基本框架搭建1、实体层&#xff08;model&#xff09;2、控制器层&#xff08;controller&#xff09;3、服务层&#xff08;service&#xff09;4、持久层&#x…

Liunx相关服务无法启动,带你一步一步找出问题和解决问题

liunx服务无法开启的原因有各种各样&#xff0c;首先我们需要找到我们究竟是为什么不能能够开启这个服务&#xff0c;这里我们先要去考虑到的一个非常重要的问题就是我们的防火墙有没有启动&#xff0c;防火墙有没有把我们的要开启相关服务的端口给封禁掉。这个是无论如何都要第…

学习记录668@项目管理之项目沟通管理和干系人管理

书上这部分的内容很无趣、很花里花哨、很杂乱&#xff0c;所以本文只摘取我认为比较有用和有意义的片段。 沟通方式 在发送方自认为已经掌握了足够的信息&#xff0c;有了自己的想法且不需要进一步听取多方意见时&#xff0c;往往选择控制力极强、参与程度最弱的“叙述方式”&a…

ES学习看这一篇文章就够了

第一章 ES简介 第1节 ES介绍 1 2 3 41、Elasticsearch是一个基于Lucene的搜索服务器 2、提供了一个分布式的全文搜索引擎,基于restful web接口 3、Elasticsearch是用Java语言开发的&#xff0c;基于Apache协议的开源项目&#xff0c;是目前最受欢迎的企业搜索引擎 4、Elastics…

机器学习(四):机器学习工作流程

文章目录 机器学习工作流程 一、什么是机器学习 二、机器学习工作流程 1、获取到的数据集介绍 2、数据基本处理 3、特征工程 4、机器学习 5、模型评估 机器学习工作流程 一、什么是机器学习 机器学习是从数据中自动分析获得模型&#xff0c;并利用模型对未知数据进行…

【程序环境和程序预处理】万字详文,忘记了,看这篇就对了

本章介绍一个test.c文件是如何生成一个test.exe文件。首先了解程序环境和程序预处理的大致流程&#xff0c;本章会分别介绍各个流程&#xff0c;但重点是翻译中的编译中的预编译阶段。 文章目录&#xff1a; 1.程序翻译环境和运行环境 1.1程序翻译中的的编译和链接 2.预编译…

Flowable进阶学习(四)任务分配与流程变量

文章目录一、任务分配1. 固定分配2. 表达式分配值表达式&#xff1a;Value expression方法表达式&#xff1a;Method expression3. 监听器分配二、流程变量1. 全局变量2. 局部变量案例&#xff1a;一、任务分配 1. 固定分配 在绘制流程图时或在流程文件中通过Assignee来指定的…