数据结构入门(C语言)顺序表的增删查改

news2024/11/24 11:07:17

目录

  • 前言
  • 1. 顺序表的概念
  • 2. 动态顺序表
    • 2.1 顺序表的初始化与销毁
    • 2.2 顺序表的尾插
    • 容量检查
    • 2.3 顺序表的尾删
    • 2.4 顺序表的头插
    • 2.5 顺序表的头删
    • 2.6 固定位置的插入
    • 2.7 固定位置的删除
    • 2.8 查找和打印
    • 2.9 修改元素
    • 主函数部分(菜单)
  • 结语

在这里插入图片描述

前言

本章会用C语言来描述数据结构中的顺序表,实现简单的增删查改操作,其中头文件包含在新建的头文件SeqList.h内,顺序表的实现在新建的Seqlist.c内,主函数Text.c将会实现菜单,方便我们进行功能的选择。

1. 顺序表的概念

在这里插入图片描述

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。

顺序表分为静态和动态两个版本,一般我们都是使用动态的版本进行操作
因为静态的版本使用定长数组存储元素,而动态的版本使用动态开辟的数组存储
在这里插入图片描述

2. 动态顺序表

在这里插入图片描述

2.1 顺序表的初始化与销毁

我们知道,一个顺序表有这么几个组成部分:起始地址,存储的数据个数,以及容量。 在进行初始化时,我们应该将起始地址置为空(NULL),个数和容量置为0。
//初始化
void SLInit(SL* ps1)
{
	ps1->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (ps1->a == NULL)
	{
		perror("malloc fail");//顺序表为空就报错,说明申请空间失败
		return;
	}
	ps1->capacity = 4;//我们设定初始空间为4个SLDatatype(这里是int)大小
	ps1->size = 0;
}

注意要释放掉内存

void SLDestory(SL* ps1)
{
	free(ps1->a);//释放
	ps1->a = NULL;//将顺序表置为空
	ps1->size = 0;//有效数字置0
	ps1->capacity = 0;//容量置0
}

2.2 顺序表的尾插

尾插,顾名思义,就是在顺序表的尾部插入数据,在实现尾插功能的同时,我们要写一个检查顺序表容量的函数,插入的时候我们要检查空间是否足够,不够则要进行扩容,足够则插入。

void SLPushBack(SL* ps1, SLDatatype x)
{
	SLCheckCapacity(ps1);//检查容量
	ps1->a[ps1->size] = x;//尾插数据
	size++
	//ps1->a[ps1->size++] = x;
	
}

容量检查

void SLCheckCapacity(SL* ps1)
{
	if (ps1->size == ps1->capacity)//有效数据大小如果和容量相等说明需要扩容了
	{
		SLDatatype* tmp = (SLDatatype*)realloc(ps1->a, sizeof(SLDatatype) * ps1->capacity * 2);
		//如果空间不够了,就扩容到原来的二倍
		if (tmp == NULL)
		{
			perror("realloc fail");//如果tmp为空说明扩容空间失败
			return;
		}
		ps1->a = tmp;//检查确保tmp不为空再赋给a
		ps1->capacity *= 2;//容量变为原来的二倍
	}

}

2.3 顺序表的尾删

实现尾删功能我们需要注意的时,说是删,但是我们可不能真删了,并不是把数据置为\n或是\0,只需要把有效数据-1就行了。
注意:不可以对要删除数的空间进行释放,因为动态开辟出的空间有一个特点:一起开辟,一起释放,在这里不可以实现。

void SLPopBack(SL* ps1)
{   //尾删数据
	assert(ps1);//暴力检查一下
	//size不能一直-1
	if(ps1->size>0)
	{
	    p->size--;
	}
}

2.4 顺序表的头插

除了需要把顺序表中【0,size-1】的元素依次向后移动一位,再插入数值
我们要从后往前向后移,因为从前往后的话数据会被覆盖
在这里插入图片描述

void SLPushFront(SL* ps1, SLDatatype x)
{
	SLCheckCapacity(ps1);//检查容量
	for (int i = ps1->size - 1; i >= 0; i--)//头插需要将顺序表中【0,size-1】的元素依次向后移动一位
	{
		ps1->a[i + 1] = ps1->a[i];
	}
	ps1->a[0] = x;   //头插数据
	ps1->size++;     //有效数据+1
}

2.5 顺序表的头删

头删很简单,与头插相反,头插是将从最后一个数开始向后覆盖,而头删是从第二个元素开始从前往后覆盖前一个元素。

void SLPopFront(SL* ps1)
{
	assert(ps1->a > 0);//暴力检查
	for (int i = 0; i < ps1->size - 1; i++)
	{
		ps1->a[i] = ps1->a[i + 1];
	}
}

2.6 固定位置的插入

思路和头插没区别,只要找到要插入的位置,将它后面位置的元素全部向后移一位,然后插入,就OK了,需要注意的是pos(插入的位置)也要进行断言

void SLInsert(SL* ps1, int pos, SLDatatype x)
{
	assert(ps1);//断言检查空指针
	assert(pos>=0 && pos <= ps1->size);//断言检查pos是否合规

	SLCheckCapacity(ps1);//检查容量
	int end = ps1->size - 1;
	while (pos <= end)
	{
		ps1->a[end + 1] = ps1->a[end];
		--end;
	}
	ps1->a[pos] = x;
	ps1->size++;
	

}

2.7 固定位置的删除

同理,从要删除的位置开始,从前往后将后一位的值赋给前一位,太简单了

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

	SLCheckCapacity(ps1);
	int start = pos+1;
	while (start < ps1->size)
	{
		ps1->a[start - 1] = ps1->a[start];
		++start;
	}
	ps1->size--;
}

2.8 查找和打印

过于简单,直接上代码

int SLFind(SL* psl, SLDatatype x)
{
	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
void SLPrint(SL* ps1)
{
	for (int i = 0; i < ps1->size; i++)
	{
		printf("%d ",ps1->a[i]);
	}
	printf("\n");
}

2.9 修改元素

void SLModify(SL* ps1, int pos, SLDatatype x)
{
	assert(ps1);
	assert(0 <= pos && pos < ps1->size);

	ps1->a[pos] = x;

}

主函数部分(菜单)

void menu()
{
	printf("***************************************\n");
	printf("1、尾插数据  2、尾删数据\n");
	printf("3、头插数据  4、头删数据\n");
	printf("5、打印数据  -1、退出\n");
	printf("***************************************\n");
}
int main()
{
	int option = 0;
	SL s;
	SLInit(&s);
	while (option != -1)
	{
		menu();
		printf("请输入你的操作:>");
		scanf("%d", &option);
		if (option == 1)
		{
			/*printf("请输入要尾插的数据,以-1结束:");
			int x = 0;
			scanf("%d", &x);
			while (x != -1)
			{
				SLPushBack(&s, x);
				scanf("%d", &x);
			}*/

			int n = 0;
			printf("请输入要尾插的数据个数,再依次输入要插入的数据:");
			scanf("%d", &n);

			int x = 0;
			while (n > 0)
			{
				scanf("%d", &x);
				SLPushBack(&s, x);
				n--;
			}
		}
		else if (option == 5)
		{
			SLPrint(&s);
		}
		else if (option == -1)
		{
			break;
		}
		else
		{
			printf("无此选项,请重新输入\n");
		}
	}

	SLDestroy(&s);

	return 0;
}

结语

就这样,顺序表从定义到结束,增删查改的功能也全部实现了,学到这里,我们就大致掌握了顺序表,同时我们也要思考一些问题:
1.中间/头部的插入,时间复杂度为O(N)
2.增容需要申请新空间,拷贝数据,释放旧空间,这个过程会有损耗
3.增容一般是以两倍的方式增长,所以必定会造成浪费,比如我们当前容量为100,已经满了,我们扩容到200,但是只新插入了5个数据,这就浪费了95个数据空间
如何处理呢?

在这里插入图片描述

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

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

相关文章

协同运力、算力、存力,加速迈向智能世界

2023年4月20日&#xff0c;华为在HAS2023期间举办“迈向智能世界”主题论坛&#xff0c;吸引了来自全球的分析师、专家学者及媒体与会。会上&#xff0c;华为ICT战略与Marketing总裁彭松发表了“持续技术创新&#xff0c;加速迈向智能世界”的主题演讲。 华为ICT战略与Marketin…

zabbix监控linux主机

1.本实验使用centos7主机&#xff0c;IP地址为10.1.60.115&#xff0c;firewalld和selinux服务已关闭 2.下载zabbix yum源(与zabbix server用一样的版本) rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm 3.安装zabbix客户…

玛雅水上乐园|玩趣系列作品集

玛雅水上乐园曾经是一座历史悠久的玛雅金字塔&#xff0c;曾用于宗教和水上航行&#xff0c;被废弃了 3000 多年。现在&#xff0c;01a1 工作室已将其改造成一个令人兴奋的旅游景点&#xff0c;在这里你可以享受美食和饮料&#xff0c;享受日光浴&#xff0c;并结交新朋友。所以…

从零学习SDK(8)SDK的集成和部署

选择使用SDK与其他平台和服务进行集成和部署的好处有&#xff1a; 简化开发流程&#xff0c;节省时间和成本&#xff0c;无需从零开始编写复杂的代码逻辑。 保证功能的稳定性和兼容性&#xff0c;避免出现各种潜在的错误和问题。 享受SDK提供方的技术支持和更新&#xff0c;获…

L频段GaN功率放大器的设计关键点

氮化镓技术的不断进步促使设备在更高的功率、电源电压和频率下工作。 ​图1 QPD1013 晶体管的照片 如图1所示&#xff0c; QPD1013晶体管采用0.50 μm GaN-on-SiC技术。它采用具有成本效益的6.6x7.2 mm DFN(双边扁平无引脚)封装&#xff0c;与传统的金属陶瓷封装相比&#xff…

ROS学习——rotors仿真下载与运行

rotors 无人机仿真主要分为两类&#xff1a;硬件在环仿真&#xff08;HITL&#xff09;和软件在环仿真&#xff08;SITL全称Software in the loop&#xff09;。 无人机软件在环仿真是指完全用计算机来模拟出无人机飞行时的状态&#xff0c;而硬件在环仿真是指计算机连接飞控…

【ArcGIS Pro二次开发】(22):生成分级用地编码和名称

在国土空间规划中&#xff0c;用地用海分类采用三级分类体系&#xff0c;共设置24种一级类、106种二级类及39 种三级类。在某些场景中&#xff0c;需要按等级归类并汇总统计。 这个小工具的作用就是通过用地编码生成三级地类&#xff0c;作为后续统计的基础。 一、要实现的功能…

研读Rust圣经解析——Rust learn-3(变量与可变性,数据类型)

研读Rust圣经解析——Rust learn-3&#xff08;变量与可变性&#xff0c;数据类型&#xff09; 变量|常量与可变性变量声明案例为什么不可变变量可变&#xff08;mut关键字&#xff09;变量可变&#xff08;覆盖&#xff09; 常量声明 数据类型标量类型整型整型字面值整型溢出问…

ECShop开源商城与COS互通:降低本地存储负载、提升访问体验

ECShop简介 ECShop是一款开源电子商务平台&#xff0c;具有简单易用、安全稳定、模块化设计等特点。它提供了完整的电子商务解决方案&#xff0c;包括商品管理、订单管理、支付管理、配送管理、会员管理、促销管理、数据统计等功能。ECShop支持多语言、多货币、多种支付方式和配…

防火墙做网关双链路接入不同ISP

USG作为校园或大型企业出口网关可以实现内网用户通过两个运营商访问Internet可以实现外网用户访问内网服务器&#xff0c;并保护内网不受网络攻击。 组网需求&#xff1a; 某学校网络通过USG连接到Internet&#xff0c;校内组网情况如下&#xff1a; 校内用户主要分布在教学…

【Java|golang】2409. 统计共同度过的日子数---golang中全局变量带来的坑

Alice 和 Bob 计划分别去罗马开会。 给你四个字符串 arriveAlice &#xff0c;leaveAlice &#xff0c;arriveBob 和 leaveBob 。Alice 会在日期 arriveAlice 到 leaveAlice 之间在城市里&#xff08;日期为闭区间&#xff09;&#xff0c;而 Bob 在日期 arriveBob 到 leaveBo…

CTFWIKI-PWN-ret2libc

目录 1.libc 2.plt 和got 3.调用system 4.flat函数 5.libc泄露 例题1 checksec ida 计算偏移量 查找system.plt 查找/bin/sh 1.ida 2.ROPgadget exp 例题2 checksec ida 思路 给出流程图 查看bss是否可以写入 exp 例题3 checksec ida 偏移量 找puts的go…

投屏市场的挑战与发展趋势

投屏的定义 投屏是指将手机、平板、电脑等设备的屏幕内容无线传输到电视、投影仪等大屏幕上的技术&#xff0c;也称为无线投屏、屏幕镜像、屏幕共享等。投屏技术可以实现多屏互动、内容共享、远程协作等功能&#xff0c;为用户提供更丰富的视听体验和更便捷的工作方式。 投屏市…

Jupyter Notebook小知识

目录 1 快捷键1.1 常用快捷键1.2 魔法函数 2 常用快捷键2.1 模式切换2.2 命令模式快捷键2.3 编辑模式快捷键3 Matplotlib绘图 4 小技巧4.1 文件默认目录的查看以及更改4.2 更改主题颜色 5 其它5.1 python中 r, b, u, f 的含义5.2 f/format():格式化操作 6 常见问题6.1 查看模块…

25K测试老鸟6年经验的面试心得,四种公司、四种问题…

这里总结了下自己今年的面试情况 先说一下自己的个人情况&#xff0c;普通二本计算机专业毕业&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能。趁着金三银四跳槽季&#xff0c;面试字节跳动测试岗技术面都已经过了&#xff0c;本来以为是…

基于OC端的Bridge-API组件化应用

前言 在移动应用开发中&#xff0c;组件化可以提高代码的模块化和重用性&#xff0c;降低耦合度。当下大部分APP都至少包含一到两种Hybrid框架&#xff0c;H5基本是必要的&#xff0c;还可能叠加React Natvie、Weex或Flutter。 对于Hybird来说&#xff0c;Native的很多能力是…

Ae:自动定向

Ae 菜单&#xff1a;图层/变换/自动定向 Auto-Orient 快捷键&#xff1a;Ctrl Alt O 自动定向 Auto-Orient是 Ae 图层中的一个附加的、隐藏实现&#xff08;不会在时间轴面板上更改属性的值&#xff09;的功能&#xff0c;它可以使得图层自动旋转或改变方向以朝向指定的运动路…

HIVE相关操作

HIVE有两种启动方式 方式1&#xff1a; bin/hive 即Hive的Shell客户端&#xff0c;可以直接写SQL方式2&#xff1a; bin/hive --service hiveserver2 后台执行脚本&#xff1a;nohup bin/hive --service hiveserver2 >> logs/hiveserver2.log 2>&1 & bin/hiv…

Vue.js列表渲染指令v-for

目录 一、原理概述 二、基本用法 &#xff08;1&#xff09;v-for循环普通数组 &#xff08;2&#xff09;v-for循环对象 &#xff08;3&#xff09;v-for循环对象数组 &#xff08;4&#xff09;v-for迭代整数 一、原理概述 v-for指令时在模板编译的代码生成阶段实现的…

6.java程序员必知必会类库之pdf处理库

前言 Pdf作为我们办公文件中的一种常用文件格式&#xff0c;很多业务中会涉及到一个功能&#xff0c;是将系统中的某些数据&#xff0c;按照要求的格式生成Pdf文件。比如常见的征信报告&#xff0c;合同文件等等&#xff0c;为此通过java代码&#xff0c;处理PDF格式的文件&am…