数据结构--顺序表(图文)

news2024/11/22 13:56:02

顺序表的概念和特点

顺序表是一种线性数据结构,它由一组数据元素构成,这些元素具有相同的特性,并按照一定的顺序排列。在顺序表中,数据元素通常存储在连续的内存空间中,这使得通过索引可以直接访问到表中的任意元素。

顺序表的特点如下:

  1. 连续的存储空间:顺序表中的元素在内存中占据一段连续的空间,这使得访问任何一个元素的时间复杂度都为O(1),即访问速度快。

  2. 动态性:顺序表可以是静态的,也可以是动态的。静态顺序表一旦初始化后,其空间大小就不能更改;而动态顺序表则可以根据需要动态地调整空间大小,即在空间不足时可以自动扩容,空间过多时可以缩容。

  3. 随机访问:由于元素存储是连续的,顺序表支持随机访问,即可以直接通过索引来访问元素,这一点与链表不同,链表需要遍历才能访问到指定位置的元素。

  4. 插入和删除操作:顺序表的插入和删除操作可能需要移动大量的元素,尤其是在插入或删除中间的元素时,时间复杂度为O(N),其中N是表中元素的数量。因此,顺序表在执行插入和删除操作时效率较低,这是它的一个缺点。

  5. 内存预分配与动态调整:在动态顺序表中,内存可以根据需要预先分配或动态调整。预分配指的是在创建顺序表时指定一个初始大小,后续根据实际情况可能进行扩容;动态调整则是在运行时根据需要增大或减小内存空间。

顺序表的实现

对比静态顺序表,动态顺序表更有优势,同样在项目中,动态顺序表的应用远远大于静态顺序表,下面我们就来实现动态顺序表。
首先创建三个文件:

  • SeqList.h —— 用于声明函数的头文件
  • SeqList.c —— 顺序表主要函数的实现
  • test.c——测试顺序表。

创建顺序表

typedef int SLDataType;//方便后续使用更改类型
typedef struct SeqList
{
	SLDataType* arr;//数组指针
	int size;//记录当前有效的数组大小
	int capacity;//记录当前总空间大小
}SL;

对顺序表初始化

void InitSeqList(SL* ps)//初始化顺序表
{
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

顺序表的销毁

void SLDestroy(SL* ps)//销毁顺序表
{
	free(ps->arr);
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

打印顺序表

void SLPrint(const SL* ps)//打印顺序表的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d", ps->arr[i]);
	}
}

在给数据表增加数据前,我们先封装一个函数,用来判断顺序表是否已满,如果满则需要开辟新空间。

判断扩容

void SLCheckCapacity(SL* ps)//判断是否需要增容
{
	assert(ps);
	if (ps->capacity == ps->size)//数组已满
	{
		int newcapacity = (ps->capacity == 0) ? 4 : 2 * ps->capacity;//如果空间为0则开辟4个空间,否则开辟原空间二倍
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity*sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

}

头插

在这里插入图片描述

void SLPushFront(SL* ps, SLDataType x)//在顺序表的头部插入数据
{
	assert(ps);
	SLCheckCapacity(ps);//判断是否需要扩容,如需要则扩容
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}

尾插

void SLPushBack(SL* ps, SLDataType x)//在顺序表的末尾插入数据
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}

指定位置插入

在这里插入图片描述

void SLInsert(SL* ps, int pos, SLDataType x)//在指定位置插入数据
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}

头删

在这里插入图片描述

void SLPopFront(SL* ps)//删除顺序表头部的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

尾删

直接size–就可以了

void SLPopBack(SL* ps)//删除顺序表尾部的数据
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

删除指定位置

在这里插入图片描述

void SLErase(SL* ps, int pos)//删除指定位置的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

查找数据

直接遍历数组找相等

int SLFind(SL* ps, SLDataType x)//在顺序表中查找数据,返回数组下标,没找到返回-1
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			return i;//找到了,返回x在顺序表中的下标
		}
	}
	return -1;//没找到
}

顺序表源码

SeqList.c

#pragma once
#include"SeqList.h"

void InitSeqList(SL* ps)//初始化顺序表
{
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

void SLDestroy(SL* ps)//销毁顺序表
{
	free(ps->arr);
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}
void SLPrint(const SL* ps)//打印顺序表的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d", ps->arr[i]);
	}
}

void SLCheckCapacity(SL* ps)//判断是否需要增容
{
	assert(ps);
	if (ps->capacity == ps->size)
	{
		int newcapacity = (ps->capacity == 0) ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, newcapacity*sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}

}
void SLPushFront(SL* ps, SLDataType x)//在顺序表的头部插入数据
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}
void SLPushBack(SL* ps, SLDataType x)//在顺序表的末尾插入数据
{
	assert(ps);
	SLCheckCapacity(ps);
	ps->arr[ps->size] = x;
	ps->size++;
}
void SLInsert(SL* ps, int pos, SLDataType x)//在指定位置插入数据
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[pos] = x;
	ps->size++;
}
void SLPopFront(SL* ps)//删除顺序表头部的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = 0; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}
void SLPopBack(SL* ps)//删除顺序表尾部的数据
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}
void SLErase(SL* ps, int pos)//删除指定位置的数据
{
	assert(ps);
	assert(ps->size);
	for (int i = pos; i < ps->size-1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}
int SLFind(SL* ps, SLDataType x)//在顺序表中查找数据,返回数组下标,没找到返回-1
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{
			return i;//找到了,返回x在顺序表中的下标
		}
	}
	return -1;//没找到

}

SeqList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef int SLDataType;//方便后续使用更改类型

typedef struct SeqList
{
	SLDataType* arr;//数组指针
	int size;//记录当前有效的数组大小
	int capacity;//记录当前总空间大小
}SL;


void InitSeqList(SL* ps);//初始化顺序表

void SLDestroy(SL* ps);//销毁顺序表

void SLPrint(const SL* ps);//打印顺序表的数据

void SLPushFront(SL* ps, SLDataType x);//在顺序表的头部插入数据

void SLPushBack(SL* ps, SLDataType x);//在顺序表的末尾插入数据

void SLInsert(SL* ps, int pos, SLDataType x);//在指定位置插入数据

void SLPopFront(SL* ps);//删除顺序表头部的数据

void SLPopBack(SL* ps);//删除顺序表尾部的数据

void SLErase(SL* ps, int pos);//删除指定位置的数据

int SLFind(SL* ps, SLDataType x);//在顺序表中查找数据,返回数组下标,没找到返回-1

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

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

相关文章

考研计组chap2数据的表示和运算

3一、进位计数制 1.r进制 第i位表示r进制的权为i 2.进制转换 &#xff08;1&#xff09;r->10 对应位置数*权值 &#xff08;2&#xff09;2 -> 16 or 8 每三位2进制数可表示1位16进制 每四位2进制数可表示1位16进制 so 分开之后转为16进制即可 eg&#xff1a;1…

欧拉函数的求解

欧拉函数的定义 欧拉函数的性质 性质1是性质2的特殊情况 性质1的理解&#xff1a;一个数a是质数&#xff0c;前面的数b与a的gcd一定是1 性质2的理解&#xff1a;1,2,…p,p1,p2…2p,…3p…p^k 其中以np结尾的序列重复了p^&#xff08;k-1&#xff09;次&#xff0c;每一次的循环…

Day10—Spark SQL基础

Spark SQL介绍 ​ Spark SQL是一个用于结构化数据处理的Spark组件。所谓结构化数据&#xff0c;是指具有Schema信息的数据&#xff0c;例如JSON、Parquet、Avro、CSV格式的数据。与基础的Spark RDD API不同&#xff0c;Spark SQL提供了对结构化数据的查询和计算接口。 Spark …

星戈瑞FITC-Cytochrome C:荧光标记细胞色素C的研究与应用

细胞色素C&#xff08;Cytochrome C&#xff09;是一种位于线粒体内膜上的蛋白质。为了深入地研究细胞色素C在细胞生物学和病理学中的功能&#xff0c;科学家们常常采用荧光标记技术对其进行追踪和观察。其中&#xff0c;异硫氰酸荧光素&#xff08;FITC&#xff09;作为一种常…

iOS原生APP开发的技术难点

iOS原生APP开发的技术难点主要体现在以下几个方面&#xff0c;总而言之&#xff0c;iOS原生APP开发是一项技术难度较高的工作&#xff0c;需要开发者具备扎实的编程基础、丰富的开发经验和良好的学习能力。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xf…

再谈量化策略失效的问题

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

数据结构之B树的理解与示例(C#)

文章目录 B树的基本概念与特点B树在C#数据结构中的应用创建一个B树节点的具体代码示例插入、删除和查找操作的示例B树在文件存储与处理中的具体应用示例总结 B树是一种自平衡的树数据结构&#xff0c;它维持数据的有序性&#xff0c;并且允许搜索、顺序访问、插入和删除的操作都…

前后端完整案例-简单模仿点点开黑抽奖

数据库 后台 源码&#xff1a;https://gitee.com/qfp17393120407/game 前台 源码&#xff1a; https://gitee.com/qfp17393120407/game-weeb vue项目打包 注意&#xff1a;打包时将IP改为自己公网IP npm run build公网页面 地址&#xff1a;点点模拟抽奖 进入页面抽奖…

电路笔记 :LM3481MM/NOPB升压模块,升压电路原理

LM3481MM/NOPB LM3481MM/NOPB 是德州仪器&#xff08;Texas Instruments&#xff09;的一款广泛应用的DC-DC控制器&#xff0c;常用于电源管理应用&#xff0c;特别是在需要升压&#xff08;boost&#xff09;、反激&#xff08;flyback&#xff09;、SEPIC或反向配置的场合。…

企业UDP文件传输工具测速的方式(下)

在前一篇文章中&#xff0c;我们深入讨论了UDP传输的基本概念和镭速UDP文件传输工具如何使用命令行快速进行速度测试。现在&#xff0c;让我们进一步探索更为高级和灵活的方法&#xff0c;即通过整合镭速UDP的动态或静态库来实现网络速度的测量&#xff0c;以及如何利用这一过程…

Java零基础之多线程篇:线程的多种创建方式

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

支持向量机 (SVM) 算法详解

支持向量机 (SVM) 算法详解 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种监督学习模型&#xff0c;广泛应用于分类和回归分析。SVM 特别适合高维数据&#xff0c;并且在处理复杂非线性数据时表现出色。本文将详细讲解 SVM 的原理、数学公式、应用场景…

[Qt的学习日常]--窗口

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、窗口的分…

最新!!单目深度估计方向文献综述--Monocular Depth Estimation: A Thorough Review

论文链接&#xff1a;https://ieeexplore.ieee.org/abstract/document/10313067 Abstract 一个是考虑人类深度感知的机制&#xff0c;另一个是包括各种深度学习方法。 这篇论文是关于单目深度估计&#xff08;Monocular Depth Estimation&#xff09;的全面综述&#xff0c;由…

Flutter第十三弹 路由和导航

目标&#xff1a; 1.Flutter怎么创建路由&#xff1f; 2.怎么实现路由跳转&#xff1f;页面返回&#xff1f; 一、路由 1.1 什么是路由&#xff1f; 路由(Route)在移动开发中通常指页面&#xff08;Page&#xff09;&#xff0c;在Android中通常指一个Activity。所谓路由管…

wsl报错在BIOS中启用虚拟化

解决&#xff1a; Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All 以高级管理员身份运行powershell&#xff0c;执行如上命令。

GoldWave软件下载 GoldWave 音频处理软件 v6.80.0 官方版下载附加详细安装步骤

准确来讲GoldWave软件防止GoldWave *原生音频插件被禁用。根据大数据结果显示回声效果&#xff1a;回声&#xff0c;顾名思义是指声音发出后经过一定的时间再返回被我们听到&#xff0c;就象在旷野上面对高山呼喊一样&#xff0c;在很多视频剪辑、配音中广泛采用&#xff0c; G…

最新版本IntelliJ IDEA安装与“坤活”使用

最新版本IntelliJ IDEA安装与“科学”使用 IntelliJ IDEA安装与坤活下载安装坤活idea1.将下面两个压缩文件解压到安装位置&#xff0c;注意路径不要包含中文空格等特殊符号2.双击 install-all-users.vbs &#xff0c;然后点击确定&#xff0c;等到出现 Done的弹窗3. 打开idea复…

【ajax基础04】form-serialize插件

目录 一&#xff1a;form-serialize插件 作用&#xff1a; 语法格式&#xff1a; 一&#xff1a;form-serialize插件 作用&#xff1a; 快速且大量的收集表单元素的值 例如上图对于多表单元素的情形&#xff0c;单靠通过”选择器获取节点.value”值的形式&#xff0c;获取…

Blazor 组件:创建、生命周期、嵌套和 UI 集成

在本文中&#xff0c;您将获得以下问题的答案。 什么是 Blazor 组件&#xff1f;如何使用组件&#xff1f;Blazor 组件的生命周期是什么&#xff1f;我们可以从一个组件调用另一个组件吗&#xff1f;如何创建 Blazor 组件&#xff1f;在组件中哪里写 C# 代码&#xff1f; 什么…