顺序表—C语言实现数据结构

news2024/9/29 11:00:50

本期带大家一起来用C语言代码实现顺序表🌈🌈🌈

文章目录

    • 一、顺序表的概念✅
    • 二、顺序表的结构✅
    • 三、顺序表的实现(动态顺序表)✅
      • 一、🔶定义顺序表结构体🔶
      • 二、🔶接口的实现🔶
        • 1.接口:初始化结构体(SLInit)🎈💡
        • 2.接口:扩容顺序表🎈💡
        • 3.接口:头插数据🎈💡
        • 4.接口:尾插数据🎈💡
        • 5.接口:头删数据🎈💡
        • 6.接口:尾删数据🎈💡
        • 7.接口:在指定位置插入数据(SLInsert)🎈💡
        • 8.接口:在指定位置删除数据🎈💡
        • 9.接口:查找某一个数据的位置(SLFind)🎈💡
        • 10.接口:修改指定下标的数据🎈💡
        • 接口11:打印函数(SLprint)🎈💡
        • 接口12:销毁(SLDestory)🎈💡
    • 四、顺序表的应用小项目✅
    • 五、感谢与交流✅

在这里插入图片描述

一、顺序表的概念✅

顺序表是一段物理地址连续的存储单元,依次存储数据元素的线性结构。分为静态顺序表与动态顺序表。 🍊 🍋 🍒

二、顺序表的结构✅

静态顺序表:使用定长数组用来存储数据
优点:操作简单,代码实现容易
缺点:定长数组很受限制,数组开小了不够用,开大了又浪费
在这里插入图片描述

动态顺序表:使用动态开辟的数组进行存储数据
优点:数组可以根据自己的需求进行调解
缺点:代码过于复杂
在这里插入图片描述

三、顺序表的实现(动态顺序表)✅

这里先建立三个文件:
1️⃣ :SeqList.h文件,用于函数声明
2️⃣ :SeqList.c文件,用于函数的定义
3️⃣ :Test.c文件,用于测试函数
建立三个文件的目的: 将顺序表作为一个项目来进行书写,方便我们的学习与观察。

一、🔶定义顺序表结构体🔶

顺序表结构体里面的成员基本的有
指向动态开辟的空间的指针a🐸
当前顺序表当中存储的数据个数size🐸
以及顺序表当前的容量capacity🐸

typedef int SLTDataType;

typedef struct SListNode
{
	SLTDataType* a;
	int size;
	int capacity;

}SL;

这里我们使用typedef对我们所存储的数据,以及顺序表结构体重命名,方便我们后续修改 🍊 🍋 🍒

二、🔶接口的实现🔶

1.接口:初始化结构体(SLInit)🎈💡

这里我们对结构体里面的内容进行初始化
在这里插入图片描述
初始化为容量为4,所存储的数据个数为0,并且利用malloc函数进行动态开辟

void SLInit(SL* psl)
{
	assert(psl);

	psl->a = (SLTDataType*)malloc(sizeof(SLTDataType) * 4);
	if (psl->a == NULL)
	{
		perror("psl::null");
		return;
	}
	psl->capacity = 4;
	psl->size = 0;

}

2.接口:扩容顺序表🎈💡

我们往顺序表当中添加数据的时候,需要判断顺序表当中数据的个数是否达到了最大容量
如果达到了最大容量,则进行扩容🍗 🍖

void SLCheckCapacity(SL* psl)
{
	if (psl->size == psl->capacity)
	{
		SLTDataType* tmp = (SLTDataType*)realloc(psl->a,sizeof(SLTDataType) * psl->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc:null");
			return;
		}
		psl-> a= tmp;
		psl->capacity *= 2;
	}
}

3.接口:头插数据🎈💡

当我们需要在顺序表的开头第一个位置插入数据的时候,我们需要进行如下操作🍗 🍖 🍝

错误想法:

在这里插入图片描述

这里是引用但是当我们从前面往后面进行覆盖的话,那么原来的数据都会被覆盖掉,所以这是一个错误的想法🍗 🍖 🍝

正确想法:
在这里插入图片描述在这里插入图片描述

void STLpushfront(SL* psl, SLTDataType s)
{
	SLCheckCapacity(psl);

	for (int i = 0; i < psl->size; i++)
	{
		psl->a[psl->size - i] = psl->a[psl->size - i - 1];

	}
	psl->a[0] = s;

	psl->size++;
}

4.接口:尾插数据🎈💡

尾插数据相对于头插数据来说是比较简单的🚀 🛸 🚁
首先我们需要先检查顺序表当中的有效数据是否已经达到了当前的容量然后
只需要将我们需要插入的数据插在顺序表当中有效数据的后面一个就行
同时让我们顺序表当中的有效数据加一即可 🍗 🍖 🍝

void STLpushback(SL* psl,SLTDataType s)
{
	SLCheckCapacity(psl);
	psl->a[psl->size] = s;
	psl->size++;

}

5.接口:头删数据🎈💡

我们删除数据的时候,需要将头部的数据进行删除
这时候我们需要采取覆盖的原理来实现
在这里插入图片描述

void SLPopFront(SL* psl)
{
	if (psl->size == 0)
	{
		printf("顺序表当中数据为空\n");
		return;
	}
	
	for (int i = 0; i < psl->size; i++)
	{
		psl->a[i] = psl->a[i + 1];

	}
	psl->size--;

}

6.接口:尾删数据🎈💡

尾删数据的话同尾插数据的原理是一样的
只需要将顺序表当中的有效数据的个数进行变化就行🚀 🛸 🚀 🛸

void SLPopBack(SL* psl)
{
	if (psl->size == 0)
	{
		printf("顺序表当中数据为空\n");
		return;
	}
	psl->size--;
}

7.接口:在指定位置插入数据(SLInsert)🎈💡

当然,添加数据的话不仅仅局限于我们的头插和尾插数据
还可以是在指定下标pos进行插入数据
函数的原型:void SLInsert(SL* ps, int pos, SLDateType x)
注意:要实现这一功能,我们依然需要一个end下标,数据从后往前依次后挪,直到pos下标移动完毕🚀 🛸
另外,别忘了检查容量。

这里是引用
我们首先需要找到当前顺序表最后一个位置的数据
然后将前面的数据赋给后一个位置⌛️ ⏳
直到找到我们的pos位置,将我们需要添加的数据添加到顺序表当中
同样在开始的时候需要检查是否扩容

void SLInsert(SL* psl, int pos, SLTDataType x)
{
	assert(psl);
	assert(pos <= psl->size && pos >= 0);
	SLCheckCapacity(psl);
	int end = psl->size;
	while ( end>pos)
	{
		psl->a[end] = psl->a[end - 1];
		end--;
	}

	psl->a[pos] = x;
	psl->size++;

}

函数拓展:该功能其实也可以实现头插和尾插,所以我们可以在头插和尾插中复用该功能

// 头插
void SeqListPushFront(SL* ps, SLDataType x)
{
	SeqListInsert(ps, 0, x);
}
 
// 尾插
void SeqListPushBack(SL* ps, SLDataType x)
{
	SeqListInsert(ps, ps->sz, x);
}

8.接口:在指定位置删除数据🎈💡

同我们的在指定位置添加数据一样
当我们需要在指定位置删除数据的时候⌛️ ⏳
我们需要传入一个下标pos进行删除的操作

然后我们需要将从下标开始的数据改为下标+1的数据

例如 a=a+1

这里是引用

void SLErase(SL* psl, int pos)
{
	assert(psl);
	assert(pos >= 0 && pos < psl->size);
	for (int i = pos; i < psl->size - 1; i++)
	{
		psl->a[i] = psl->a[i + 1];
	}

	psl->size--;

}

函数拓展:该功能其实也可以实现头删和尾插=删,所以我们可以在头删和尾插】删中复用该功能

// 头删
void SeqListPopFront(SL* ps)
{
	SeqListErase(ps, 0);
}
 
// 尾删
void SeqListPopBack(SL* ps)
{
	SeqListErase(ps, ps->sz - 1);
}

9.接口:查找某一个数据的位置(SLFind)🎈💡

查找顺序表当中是否存在某个数据

如果存在的话就返回所对应的下标
不存在的话则返回-1

int SLFind(SL* psl, SLTDataType x)
{

	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
			return i;
	}
	return -1;
}

10.接口:修改指定下标的数据🎈💡

首先判断传入的下标是否合法❓❓❓
合法的话则将对应下标的数据修改

void SLModify(SL* psl, int pos, SLTDataType x)
{
	assert(psl);

	assert(0 < pos && pos < psl->size);

	psl->a[pos] = x;
}

接口11:打印函数(SLprint)🎈💡

主要利用顺序表当中有效数据的个数进行数据的打印🌎 🌍

void SLprint(SL* psl)
{

	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		/*printf("%d ", *(psl->a + i));*/

		printf("%d ", psl->a[i]);
	}
	printf("\n");

}

接口12:销毁(SLDestory)🎈💡

由于我们的顺序表是动态开辟出来的的
所以我们需要在结束程序的时候需要将开辟出来的空间进行销毁
避免内存泄漏🌎 🌍

void SLDestroy(SL* psl)
{
	assert(psl);
	free(psl->a);

	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;

}

四、顺序表的应用小项目✅

顺序表实现通讯录

五、感谢与交流✅

🌹🌹🌹如果大家通过本篇博客收获了,对顺序表有了新的了解的话
那么希望支持一下哦如果还有不明白的,疑惑的话,或者什么比较好的建议的话,可以发到评论区,
我们一起解决,共同进步 ❗️❗️❗️
最后谢谢大家❗️❗️❗️💯💯💯
在这里插入图片描述

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

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

相关文章

【原理图专题】案例:从集成的电平转换芯片换成三极管分立电平转换怎么就报异常

本案例是一个已经小批量量产的设备,不是我测试出来的,但是也算是我之前一手造成的,因为原理图这部分是我修改的。 异常发现最近生产的整机有部分非接读卡时无法控制到蜂鸣器发声音。我们的设计是这样的,有两个MCU互相通信,一个MCU是控制蜂鸣器的,另一个MCU通过SPI与非接芯…

UEFI Driver Services

为UEFI驱动程序提供的UEFI引导服务和UEFI运行时服务一般可分为三个方面&#xff1a; 驱动通常使用很少使用的服务不应该使用的服务 UEFI驱动程序通常使用的服务 下表列出了UEFI驱动程序通常使用的UEFI服务。接下来&#xff0c;讨论将简要描述每种服务&#xff0c;它们为什么…

scala函数参数

目录 可变参数如果参数列表在存在多个参数&#xff0c;那么可变参数一般放置在最后参数默认值&#xff0c;一般将有默认值的参数放置在参数列表的后面带名参数&#xff08;一般不使用&#xff0c;除多个参数有默认值且只需给极少个参数赋值的情况&#xff09; 可变参数 当有不…

无线测温在线监测系统工作原理与产品选型

摘要&#xff1a;本文首先介绍了无线测温在线监测系统的基本工作原理以及软硬件组成&#xff0c;重点介绍了在线监测的无线测温技术特点。在此研究基础上&#xff0c;探讨了无线测温在线监测系统在实际工作场景中的应用案例&#xff0c;证明了其在温度检测方面的重要应用价值。…

浅谈数字化工厂五大核心系统

一、什么是数字化工厂 数字化工厂是将数字技术应用于工厂生产、管理和运营中的一种方式&#xff0c;可以帮助企业提高生产效率和质量&#xff0c;降低成本和风险&#xff0c;提高竞争力和市场份额。数字化工厂是中小制造业企业自主建设制造业信息化的途径。 简道云数字化工厂解…

stm32虚拟串口无法连接,驱动安装,DFU驱动安装

虚拟usb串口设备 插上设备后, COM这里多了一个端口, 但是其用串口调试助手无法打开 在其他设备这里多了一个STM32xx Virtual COM, 更新驱动程序 浏览我的电脑以查找驱动程序让我从计算机上的可用驱动列表中选取端口(COM和LPT)厂商: STMicroelectronics 型号: STMicroelectroni…

倾斜摄影三维模型、激光点云、正射影像、数字高程模型如何实现在线浏览?

四维轻云是成都远石技术团队基于浏览器打造的一款地理空间数据管理云平台&#xff0c;可实现TB级大规模倾斜摄影三维模型发布管理&#xff0c;并支持私有化部署和高阶功能定制化开发。 1、注册登录 首先在四维轻云官网点击「立即试用」按钮&#xff0c;进入登录页面并点击「注…

手写vue(三)模板渲染解析

一、目标 创建一个Vue实例时&#xff0c;我们可以传入el配置项&#xff0c;去指定一个DOM元素作为Vue容器&#xff0c;而这个Vue容器中&#xff0c;可以使用例如插值表达式等Vue框架提供的语法&#xff0c;并且能够渲染到浏览器页面上。 而浏览器并不能解析这些Vue语法&#xf…

Ubuntu20.04软件安装大全

目录 Ubuntu20.04 软件安装大全前言1. Windows和Ubuntu双系统安装1.1 下载Ubuntu系统镜像1.2 磁盘分区1.3 GPT分区安装Ubuntu1.4 系统完成后的一些设置1.5 遇到的一些小bug 2. 换源2.1 apt换源2.2 pip换源 3. 显卡驱动安装3.1 卸载显卡驱动3.2 准备工作3.3 驱动安装3.4 验证 4.…

分享5款小软件,让你打造更舒适的办公电脑

每次发现实用的小工具,都会有种小小的成就感&#xff0c;这也是我喜欢收集和分享高效工具的原因。 图标定制软件——CustomizerGod CustomizerGod是一款强大的电脑图标定制软件&#xff0c;可以让你随心所欲地改变系统中的任何图标。你可以使用CustomizerGod来修改桌面、任务…

Node 01-Buffer

Buffer&#xff08;缓冲器&#xff09; 概念 Buffer 是一个类似于数组的 对象 &#xff0c;用于表示固定长度的字节序列 Buffer 本质是一段内存空间&#xff0c;专门用来处理 二进制数据 。 特点 Buffer 大小固定且无法调整Buffer 性能较好&#xff0c;可以直接对计算机内存…

AI智能课程第一讲:chatgpt介绍

AI应用现状 用AI艺术创作 一个小女孩打折手电筒在侏罗世纪公园找恐龙。 AI用于医疗行业 AI辅助驾驶 AI广告投放上的应用 什么是chatgpt&#xff1f; chatgpt相关技术的发展 为什么用chatgpt写代码会特别的快呢&#xff1f; 因为它集成了GitHub上所有开发者的库公用资源&…

战胜儿童乙肝,早治是关键

在我国实施新生儿乙型肝炎疫苗免疫规划后&#xff0c;母婴传播量明显减少。2014年&#xff0c;中国疾病预防控制中心对全国1-29岁人群乙型肝炎血清流行病学调查结果显示&#xff0c;1-4岁人群HBSAg流行率仅为0.32%&#xff0c;较1992年下降96.7%。然而&#xff0c;仍有6%的新生…

X509证书中的Signature Algorithm

Signature Algorithm在X509中的结构 分别在整个证书结构中Certificate的第二项和 TBSCertificate结构中的第三项&#xff1a; 对于ECC和国密算法 The AlgorithmIdentifier parameters field MUST be absent. 各种签名算法的OID: ECC的: ecdsa-with-SHA256 OBJECT IDENTIFI…

计网第五章.运输层—TCP的三次握手与四次挥手

以下来自湖科大计算机网络公开课笔记及个人所搜集资料 目录 一、TCP三次握手建立连接为什么TCP客户进程最后还要发送一个普通的TCP确认报文段呢&#xff1f;能不能两次握手&#xff1f;总结&#xff1a; 二、TCP四次挥手释放连接四次挥手过程问题1&#xff1a;TCP客户进程在发送…

【推荐】1657- 灵活可扩展,2023年值得尝试的13款富文本编辑器

作为前端开发人员&#xff0c;我们经常需要为网站和应用程序添加文本内容。与传统的文本编辑器不同&#xff0c;富文本编辑器可让您轻松创建各种类型的文本内容&#xff0c;包括加粗字体、斜体字、框架、列表、图片和视频等。 本文我将向大家推荐 13 款开源的灵活可拓展的富文本…

HTML5的新特性,CSS3的新特性

1.HTML5的新特性 HTML5的新特性主要针对以前的不足&#xff0c;增加了一些新的标签&#xff0c;新的表单&#xff0c;新的表单属性等。 这些新特性都有兼容性问题&#xff0c;基本是IE9以上版本的浏览器才支持&#xff0c;如果不考虑兼容性问题&#xff0c;可以大量使用这些新…

Docker之Dockerfile

Dockerfile 1. Dockerfile 简介2. Dockerfile 构建过程3. Dockerfile 常用指令4. 实战测试 centos5. 实战测试 Tomcat镜像6. 发布自己的镜像6.1 DockerHub6.2 阿里云镜像服务 7. 小结 1. Dockerfile 简介 Dockerfile 是用来构建docker 镜像的文件&#xff01;是一个命令参数脚本…

MySQL 窗口函数

MySQL的窗口函数是一种特殊类型的聚合函数&#xff0c;使用窗口函数可以使查询更高效&#xff0c;因为它们可以避免在多个聚合阶段中重复扫描相同的行。还可以使用窗口函数来计算一些有趣的结果&#xff0c;例如排名、百分比和移动平均值等。 目录 一、认识窗口函数1、窗口函数…

重入的问题搞清楚

很久很久之前&#xff0c;写入重入问题的文章 如果你在笔试的实际&#xff0c;面试官问——下面这个代码有什么问题&#xff1f; #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #incl…