【数据结构】顺序表:随机访问的速度快到飞起

news2024/9/24 18:51:13

在这里插入图片描述

  • 👑专栏内容:数据结构
  • ⛪个人主页:子夜的星的主页
  • 💕座右铭:日拱一卒,功不唐捐

文章目录

  • 一、前言
  • 二、线性表
  • 三、顺序表
    • 1、定义
    • 2、静态顺序表
    • 3、动态顺序表
    • 4、接口实现
      • Ⅰ、初始化
      • Ⅱ、销毁
      • Ⅲ、增容
      • Ⅳ、插入
      • Ⅴ、删除
      • Ⅵ、查找
      • Ⅶ、打印
  • 四、总结
    • 1、分类
    • 2、特点
    • 3、缺陷


一、前言

前面介绍了如何分析一个算法的时间复杂度和空间复杂度,但那些都是数据结构学习的预备工作。而本文介绍的顺序表,则是数据结构中较为基础的类型。虽然基础,但也有它自己独有的特性,具体是那些特性,就让我们往下看吧。

在这里插入图片描述

二、线性表

再介绍顺序表之前,我们先认识一下线性表。

线性表,全名为线性存储结构。即 “ 把所有数据用一根线儿串起来,再存储到物理空间中 ”。如下图所示,既然线性表是排成像一条线一样的结构,那么每个线性表上的数据最多只有前和后两个方向。

顺序表、链表、栈、队列等都属于线性表中的一种。

在这里插入图片描述

而与线性表的概念相对应的是非线性表。
非线性表里的数据之间并不是一对一关系,而是一对多或多对多关系。

树、图、堆等都属于非线性表中的一种。

在这里插入图片描述

三、顺序表

1、定义

维基百科:顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。

好吧,那就直接看定义里面的重点。
顺序表是用一段连续的存储单元依次存储数据元素的线性结构

在这里插入图片描述

2、静态顺序表

静态顺序表就是,使用定长数组存储元素。再简单点说,就是数组的容量是固定的,用完就没了。少了不够,多了浪费。

#define N 100   		 //(0)
typedef int SLDataType;  //(1)
typedef struct SeqList   
{
    SLDataType arr[N];	 //(2)
    size_t size;		 //(3)
}SeqList;				 //(4)

(0)规定N等于100
(1)重新定义int类型名为SLDataType(便于后面修改类型)
(2)静态数组来保存顺序表中的元素,一共N个位置(最多存入N个元素)
(3)顺序表当前长度
(4)定义SeqList代表这个结构体类型名

3、动态顺序表

动态顺序表,是先开辟一块小空间,然后利用realloc函数或malloc函数按需开辟空间,空间不够了,就开辟,多了就不开辟。

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* array;//(0)
	size_t size;	  //(1)
	size_t capicity;  //(2)
}SeqList;

(0)指向动态开辟的数组
(1)顺序表当前长度
(2)容量空间的大小

在这里插入图片描述
额…那是因为开辟空间的接口函数还都没写呢。

4、接口实现

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

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* array;
	size_t size;	 
	size_t capicity;  
}SeqList;

Ⅰ、初始化

初始化的目的就是清理内存中可能遗留的“脏数据”。

void SeqListInit(SeqList* psl)
{
	assert(psl);//断言防止其为空指针
	psl->array=NULL;//讲该指针置空
	psl->size = 0;//设置有效数据个数为0
	psl->capacity = 0;//设置空间容量为0
}

assert函数的作用就是:求表达式的值,当结果为假时,打印诊断消息并中止程序。它的作用就像是下面这个if函数。

if(假设成立)
{
     程序正常运行;
}
else
{
      报错&&终止程序!(避免由程序运行引起更大的错误)  
}

Ⅱ、销毁

void SeqListDestory(SeqList* psl)
{
	assert(psl);
	//释放动态开辟的空间
	if (psl->array)
	{
		free(psl->array);
		psl->array = NULL;
		psl->capacity = 0;
		psl->size = 0;
	}
}

Ⅲ、增容

利用realloc函数或者malloc函数给一个表增容,最先做的就是先检查顺序表内元素个数是否已达顺序表容量上限。若已达上限,那么我们就需要先对顺序表进行扩容,然后才能增加数据。

void SeqListCheckCapacity(SeqList* psl)
{
	assert(psl);

	if (psl->size == psl->capacity)
	{
		int newCapacity = psl->capacity == 0 ? 4 : psl->capacity * 2;
		SeqListDataType* tmp = (SeqListDataType*)realloc(psl->array, newCapacity * sizeof(SeqListDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		psl->array = tmp;
		psl->capacity = newCapacity;
	}
}

在这里插入图片描述

Ⅳ、插入

因为顺序表中每个数据元素在内存中是连续存储的,所以如果要在某个位置插入一个元素,则需要把原来该位置的元素依次向后移动。
在这里插入图片描述

  • 头插
void SeqListPushFront(SeqList* psl, SeqListDataType x)
{
	assert(psl);
	SeqListCheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->array[end + 1] = psl->array[end];
		end--;
	}
    //或者用for循环
    //	for (int i = psl->size - 1; i >= 0; i--)  
    //顺序表中[0,size-1]的元素依次向后挪动一位
	//{
	//	psl->array[i + 1] = psl->array[i];
	//}
	psl->array[0] = x;
	psl->size++;
}
  • 中间插
void SeqListInsert(SeqList* psl, int pos, SeqListDataType x)
{
	assert(psl);
	assert(pos >= 0);
	assert(pos <= psl ->size);

	SeqListCheckCapacity(psl);
	int end = psl->size - 1;
	while (end >= pos)
	{
		psl->array[end + 1] = psl->array[end];
		end--;
	}

	psl->array[pos] = x;
	psl->size++;
}
  • 尾插
void SeqListPushBack(SeqList* psl, SeqListDataType x)
{
	assert(psl);
	SLCheckCapacity(psl);
	psl->array[psl->size] = x;
	psl->size++;
}

在这里插入图片描述

  • 中插改头插
void SeqListPushFront(SeqList* psl, SeqListDataType x)
{
   SeqListInsert(psl, 0, x);
}
  • 中插改尾插
void SeqListPushBack(SeqList*psl,SeqListDataType X)
{
    SLInsert(psl, ps->size, x);
}

Ⅴ、删除

因为顺序表中每个数据元素在内存中是连续存储的,所以如果删除某个位置的元素,则需要依次把该位置后面的元素依次向前移动。
在这里插入图片描述

  • 头删
void SeqListPopFront(SeqList* psl)
{
	assert(psl);  //断言
    assert(psl->size>0);//防止数据为0时还删数据
	assert(psl->size > 0);  //顺序表不能为空
	int begin = 1;
    while(begin<ps->size)
    {
        psl->array[begin-1]=psl->array[begin];
        begin++;
    }
//	int i = 0;
//	for (i = 1; i < psl->size; i++)  //顺序表中[1,size-1]的元素依次向前挪动一位
//	{
//		psl->array[i - 1] = psl->array[i];
//	}
	psl->size--;  //有效数据个数-1
}
  • 中删
void SeqListErase(SeqList* psl, int pos)
{
	assert(psl);
	assert(pos >= 0);
	assert(pos < psl->size);
	int begin = pos + 1;
	while (begin < psl->size)
	{
		psl->array[begin - 1] = psl->array[begin];
		begin++;
	}
	psl->size--;
}
  • 尾删
void SeqListPopBack(SeqList* psl)
{
	assert(ps);
	assert(ps->size > 0);
	psl->array[ps->size - 1] = 0;
	psl->size--;
}

在这里插入图片描述

  • 中删改头删
void SeqListPopFront(SeqList* psl)
{
    SeqListErase(psl, 0);//直接调用
}
  • 中删改尾删
void SeqListPopBack(SeqList*psl)
{
    SeqListErase(psl, psl->size-1);//直接调用
}

Ⅵ、查找

int SeqListFind(SeqList* psl, SeqListDataType x, int begin)
{
	assert(psl);
	for (int i = begin; i < psl->size; i++) //遍历顺序表
	{
		if (ps->array[i] == x)
		{
			return i; //找到了返回下表
		}
	}
	return -1; //没找到
}

Ⅶ、打印

void SeqListPrint(SeqList* psl)
{
	assert(psl);
	if (psl->size == 0)
	{
		printf("空表");
		return;
	}
	for (int i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->array[i]);
	}
	printf("\n");
}

四、总结

顺序表的实际应用:C语言顺序表实现学生管理系统

在这里插入图片描述

1、分类

顺序表是线性表中的一种,顺序表可以分为:
1.静态顺序表:使用定长数组存储元素。
2.动态顺序表:使用动态开辟的数组存储。

2、特点

顺序表的特点:
①随机访问,即可以在 O(1) 时间内找到第 i 个元素。(访问速度极快)
②存储密度高,每个节点只存储数据元素
③拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)
④插入、删除操作不方便,需要移动大量元素

3、缺陷

1.空间不够,需要扩容。扩容是有代价的,并且会存在空间浪费。
2.头部或者中部的插入删除,需要挪动数据,效率低。

在这里插入图片描述

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

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

相关文章

中国各省人力资本测算就业人员受教育程度构成(2000-2021年)

数据来源&#xff1a;自主整理 时间跨度&#xff1a;2000-2021年 区域范围&#xff1a;全国各省 指标说明&#xff1a; 人力资本测算公式&#xff1a;&#xff08;小学*6初中*9高中*12大专及以上*16&#xff09;/六岁及以上人口 参考文献&#xff1a; [1]罗仁福, 刘承芳,…

Python pandas「原有或者新建」Excel中「追加新或者新建」sheet

1.pandas原有Excel中追加新sheet 使用Pandas库&#xff0c;我们可以轻松将数据追加到现有的Excel工作簿中的新工作表中。以下是追加新工作表的简单步骤&#xff1a; 读取现有的Excel文件 使用Pandas库中的read_excel()函数读取现有的Excel文件。指定Excel文件的路径和文件名&a…

多模态机器学习入门Tutorial on MultiModal Machine Learning——第一堂课个人学习内容

文章目录课程记录核心技术Core Technical Challengesrepresentation表示alignment对齐转换translationFusion融合co-learning共同学习总结Course Syllabus教学大纲个人总结第一周的安排相关连接课程记录 这部分是自己看视频&#xff0c;然后截屏&#xff0c;记录下来的这部分的…

C生万物 | 模拟实现库函数strcpy之梅开n度

文章目录【梅开一度】&#xff1a;观察库函数strcpy()的实现【梅开二度】&#xff1a;模仿实现strcpy()【梅开三度】&#xff1a;优化简练代码【梅开四度】&#xff1a;assert()断言拦截【梅开五度】&#xff1a;const修饰常量指针【梅开六度】&#xff1a;还可以有返回值哦&am…

如何使用linux服务器多核跑程序和unhashable type: ‘list‘报错的解决方案

问题描述 在使用服务器多核跑程序的时候&#xff0c;需要把核心的程序抽取出来&#xff0c;然后提供迭代参数。然后就可以使用多核去跑程序了。但是在执行的过程中报错如下&#xff1a; Exception has occurred: TypeError unhashable type: list File "/home/LIST_208…

【机器学习 深度学习】通俗讲解集成学习算法

目录&#xff1a;集成学习一、机器学习中的集成学习1.1 定义1.2 分类器(Classifier)1.2.1 决策树分类器1.2.2 朴素贝叶斯分类器1.2.3 AdaBoost算法1.2.4 支持向量机1.2.5 K近邻算法1.3 集成学习方法1.3.1 自助聚合(Bagging)1.3.2 提升法(Boosting)1.3.2.1 自适应adaboost1.3.3 …

【C语言编译器】02 Windows下 7 种C语言IDE的使用(万字长文警告,含Visual Studio多个版本)

目录一、Visual Studio1.1 VS 20101.2 VS 20151.21 简介1.22 使用1.3 VS 20171.31 简介1.32 使用1.4 VS 20191.41 简介1.42 使用1.5 VS 20221.6 VS 安全函数问题1.7 VS “无法查找或打开PDB文件” 问题二、CLion2.1 CLion简介及安装2.2 使用CLion编写C程序三、Dev C3.1 Dev C简…

【ubuntu 22.04不识别ch340串口】

这个真是挺无语的&#xff0c;发现国内厂商普遍对开源环境不感兴趣&#xff0c;ch340官方linux驱动好像被厂家忘了&#xff0c;现在放出来的驱动还是上古内核版本&#xff1a; 于是&#xff0c;驱动居然要用户自己编译安装。。还好网上有不少大神&#xff1a;链接&#xff0c;…

一起学 pixijs(3):Sprite

大家好&#xff0c;我是前端西瓜哥。今天来学习 pixijs 的 Sprite。 Sprite pixijs 的 Sprite 类用于将一些纹理&#xff08;Texture&#xff09;渲染到屏幕上。 Sprite 直译为 “精灵”&#xff0c;是游戏开发中常见的术语&#xff0c;就是将一个角色的多个动作放到一个图片…

零基础小白如何学会Java?

Java作为目前使用最广泛的编程语言&#xff0c;自身在常见的企业级业务应用程序以及Android应用程序等方面都有突出的表现。作为跨平台语言&#xff0c;具有安全性、易用性、通用性等特点&#xff0c;被特意设计用于互联网的分布式环境。 对于很多喜欢代码的小伙伴来说Java都是…

音乐播放器-- 以及数据库数据存储

运行环境 &#xff1a; java1.8 数据库以及代码编写工具 &#xff1a; sqlserver -- mysql 也可以 工具 eclipse 编码gbk窗体 &#xff1a; Swing使用了jaudiotagger 进行了音乐处理 图片展示 ----- 空闲时间 做出来玩的项目 部分功能还没有完善 完善了的功能 音乐 /// 主页 &a…

SheetJS的部分操作

成文时间&#xff1a;2023年2月18日 使用版本&#xff1a;"xlsx": "^0.18.5" 碎碎念&#xff1a; 有错请指正。 这个库自说自话升级到0.19。旧版的文档我记得当时是直接写在github的README上。 我不太会使用github&#xff0c;现在我不知道去哪里可以找到…

SpringMvc介绍。

目录 1、SpringMvc概述 1、基本介绍 2、工作流程 3、bean加载控制 二、请求 1、请求映射路径 2、请求方式 3、请求参数 4、请求参数&#xff08;传递json数据&#xff09; 5、日期类型参数传递 三、响应 四、REST风格 1、REST简介 2、RESTful入门案例 3、RESTfu…

信号完整性设计规则之串扰最小化

本文内容从《信号完整性与电源完整性分析》整理而来&#xff0c;加入了自己的理解&#xff0c;如有错误&#xff0c;欢迎批评指正。 1. 对于微带线和带状线&#xff0c;保持相邻信号路径的间距至少为线宽的2倍。 减小串扰的一种方式就是增大线间距&#xff0c;使线间距等于线…

GeniE 实用教程(三)属性

目 录一、前言二、材料属性三、截面属性3.1 梁横截面3.2 板壳厚度3.3 截面赋予四、截面偏置4.1 梁偏置4.2 板壳偏置五、局部轴方向5.1 梁的局部轴5.2 板壳的法向六、水力属性6.1 湿表面属性6.2 水动力参数七、参考文献一、前言 SESAM &#xff08;Super Element Structure Anal…

23 pandas Excel文件的拆分与合并

文章目录一个文件夹下多个工作簿的合并【单独Sheet】同一工作簿中多个Sheet合并ExcelWriter针对不同工作表的操作将一个工作表拆分成多个工作表将一个工作表拆分成多个工作簿一个文件夹下多个工作簿的合并【单独Sheet】 1把文件夹下所有的文件都遍历出来2循环读取文件放入一个…

【C++】再谈vscode界面调试C++程序(linux) - 知识点目录

再谈vscode界面调试C程序&#xff08;linux&#xff09; 配套文档&#xff1a;vscode界面调试C程序&#xff08;linux&#xff09; 命令解释 g -g ../main.cpp 编译main.cpp文件&#xff1b; -g&#xff1a;生成调试信息。编译器会在可执行文件中嵌入符号表和源代码文件名&…

程序员必备的技能-深入理解 Linux 内核拆解

841 页的《深入理解 Linux内核》堪称经典&#xff0c;时隔多年打开&#xff0c;泛黄的纸张上面仍然跳跃出一个个让人心潮澎湃的知识点&#xff0c;突然让我想起一位微信朋友的昵称&#xff1a;知识的舔狗&#xff01;拆&#xff0c;开始~前言第一章 绪论Linux与其他类Unix内核…

springmvc汽车企业公司网站的系统设计 java ssm

红旗汽车走进社区&#xff0c;走进生活&#xff0c;成为当今生活中不可缺少的一部分。随着汽车行业的发展&#xff0c;加强管理和规范管理司促进红旗汽车网站健康发展的重要推动力。在我国迎来良好的发展机遇&#xff0c;但同时也确实有许多问题的需要研究和探讨。系统主要完成…

pvs中pv显示[unknown]解决方法、正确剔除一个vg流程方法【不影响vg已有的lv数据】、vgs容量和硬盘容量显示不一致解决方法

文章目录pvs中pv显示[unknown]解决方法报错产生情况报错说明解决方法解决方法【无法修复情况&#xff0c;重要&#xff01;&#xff01;&#xff01;】解决方法【正常情况下】正常的剔除一个vg流程【不影响vg已有lv】环境准备强制剔除正常剔除vgs容量和硬盘容量显示不一致解决方…