线性表——顺序表

文章目录

  • 一:线性表
  • 二:顺序表
    • 1:概念与结构
      • 1:静态顺序表
      • 2:动态顺序表
    • 2:动态顺序表的代码实现
      • 1:结构
      • 2:接口实现
        • 1:初始化
        • 2:释放内存
        • 3:检查容量
        • 4:尾插
        • 5:尾删
        • 6:头插
        • 7:头删
        • 8:顺序表在任意位置(pos)插入x
        • 9:顺序表在任意位置(pos)删除x
        • 10:在顺序表中查找指定值
      • 3:接口优化
        • 1:尾插尾删优化
          • 尾插
          • 尾删
        • 2:头插头删优化
          • 头插
          • 头删

一:线性表

线性表(linear list)是n个具有相同特性的数据元素有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储

在这里插入图片描述

二:顺序表

1:概念与结构

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

1:静态顺序表

静态顺序表:使用定长数组存储元素

#pragma once //为了避免同一个头文件被包含(include)多次

//静态顺序表:使用定长数组存储元素.(不太实用)
// Max太小了不够用 太大了怕浪费
#define Max 10
//定长数组不只是int类型的,
//因此用结构体来方便修改其他数据类型
typedef int SLDataType;//顺序表SL的DataType
typedef struct SeqList
{
	//int a[Max];//定长数组
	SLDataType a[Max];
	size_t size;//记录数组中的有效数据
}SL;

静态顺序表一般不太实用 我们经常用的是动态顺序表

2:动态顺序表

动态顺序表:使用动态开辟的数组存储

2:动态顺序表的代码实现

1:结构

//结构
typedef int SLDataType;//顺序表SL的DataType
typedef struct SeqList
{
	SLDataType* a;//定义一个指针指向动态开辟的数组
	size_t size;//记录数组中的有效数据(指向最后数据的下一个位置)
	size_t capcity;//空间容量的大小
}SL;

在这里插入图片描述

2:接口实现

1:初始化

将有效数据个数和容量都初始化为0,并将指针指空

void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->size = ps->capcity = 0;
}

2:释放内存

释放顺序表的空间,并将指针指空,容量和数据个数置0 (只有在数组不为空的情况下才会销毁)

void SLDestroy(SL* ps)
{
	//if (ps->a != NULL)
	if (ps->a)//非0为真
	{
		free(ps->a);
		ps->a = NULL;
		ps->size = ps->capcity = 0;
	}		
}

3:检查容量

在增加数据的时候,首先需要判断顺序表的容量是否够用,如果不够用就需要增容。

每次扩容扩成原来容量二倍的原因:

  • 如果一次扩多了,会造成空间的浪费
  • 扩的少了在增加数据的时候就需要频繁扩容,降低了程序的效率。realloc函数扩容存在原地扩容和异地扩容俩种情况,如果是异地的话无疑会更加增加扩容的成本,需要花费更多时间。
  • 综合考虑俩种因素,扩成原来的二倍是比较合理的

我们知道,开辟动态空间使用的是malloc或者calloc函数,而realloc是用来扩容的,而我们这里仅使用realloc既实现开辟,又实现扩容。-

仅用realloc不用malloc的原因:

  • malloc仅在初始化后容量为0的时候开辟动态空间使用,之后的扩容都是使用到realloc,如果分情况写就会比较冗余
  • realloc同样可以实现malloc的功能,当传给realloc的指针是空指针NULL的时候,realloc的功能和malloc是一样的,所以我们在初始化时也是将管理数据的指针设为空指针的
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	//扩容
	if (ps->size == ps->capcity)//如果越界了或者为NULL
	{
		//一般2倍扩容
		//如果是0,则空间为4个(随机)
		int newCapcity = ps->capcity * 2 == 0 ? 4 : ps->capcity * 2;
		//空间容量应当将个数*字节
		//realloc:返回新开的数组空间的地址,可能第一次为NULL,也有可能接收失败
		//因此用tmp变量接收
		SLDataType* tmp = realloc(ps->a, newCapcity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc is fail");
			exit(-1);//异常终止返回-1,正常结束返回0
		}
		ps->a = tmp;
		ps->capcity = newCapcity;
	}
}

4:尾插

在数组尾部插入数据,首先要考虑扩容问题,再插入数据,同时元素个数增加

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);//防止数组越界
	ps->a[ps->size] = x;
	ps->size++;
}

5:尾删

删除数组尾部的数据,同时元素个数减小,要考虑数组为空不能删的情况

void SLPopBack(SL* ps)
{
	//温柔的检查
	//if (ps->size == 0) 
	//{
	//	return;
	//}

	//暴力检查
	assert(ps->size > 0);//为真就通过运行,为假就结束运行了
	ps->size--;
}

6:头插

在数组尾部插入数据,首先要考虑扩容问题,再将数组的每个元素依次向后移动一位,再在第一个位置插入数据即可,同时元素个数增加

void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//从最后一个数据开始依次向后挪动一位数据进行覆盖
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;//头部插入数据
	ps->size++;
}

7:头删

void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size > 0);
	//从第一个元素开始删
	int begin = 0;
	while (begin < ps->size - 1)
	{
		ps->a[begin] = ps->a[begin + 1];
		begin++;
	}
	//或者从第二个元素开始删
	/*int begin = 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}*/
	ps->size--;
}

在这里插入图片描述

8:顺序表在任意位置(pos)插入x

//任意位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	//防止越界
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//检查容量
	SLCheckCapacity(ps);

	//从最后一个数据到目标位置结束开始依次向后挪动一位数据覆盖
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;//在pos处插入数据
	ps->size++;
}

9:顺序表在任意位置(pos)删除x

void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	int begin = pos;
	while (begin < ps->size - 1)
	{
		ps->a[begin] = ps->a[begin + 1];
		begin++;
	}
	ps->size--;
	//或者
	/*int begin = pos + 1;
	while (begin < ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;*/
}

10:在顺序表中查找指定值

//查找指定值
int SLFind(SL* ps, SLDataType x, int begin)
{
	assert(ps);
	for (int i = begin; i < ps->size; ++i)
	{
		if (ps->a[i] == x)
		{
			return i;//找到直接返回下标
		}
	}
	//查找不到,返回-1
	return -1;
}

3:接口优化

1:尾插尾删优化

尾插
void SLPushBack(SL* ps, SLDataType x)
{
	//在下标为size的位置插入数据(末尾元素的下一个)
	SLInsert(ps, ps->size, x);
}
尾删
void SLPopBack(SL* ps)
{
	//删除下标为size-1的数据(末尾元素)
	SLErase(ps, ps->size - 1);
}

2:头插头删优化

头插
void SLPushFront(SL* ps, SLDataType x)
{	
	//在下标为0的位置插入数据(首元素)
	SLInsert(ps, 0, x);
}
头删
void SLPopFront(SL* ps)
{
	//删除下标为0的数据(首元素)
	SLErase(ps, 0);
}

具体代码可见:https://gitee.com/calcium-oxide-2411/test_c

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下最小化安装CentOS-7.6(保姆级)

文章目录安装包开始安装一、 新建一个虚拟机二、配置安装CentOS7.6二、开始安装CentOS三、配置CentOS并下载基本信息安装包 链接&#xff1a;https://pan.baidu.com/s/1DodB-kDy1yiNQ7B5IxwYyg 提取码&#xff1a;p19i 开始安装 一、 新建一个虚拟机 1、 打开VMWare&#x…

刷题笔记【5】| 快速刷完67道剑指offer(Java版)

本文已收录于专栏&#x1f33b;《刷题笔记》文章目录前言&#x1f3a8; 1、合并两个有序链表题目描述思路一&#xff08;递归&#xff09;思路二&#xff08;双指针&#xff09;&#x1f3a8; 2、树的子结构题目描述思路一&#xff08;递归&#xff09;&#x1f3a8; 3、二叉树…

Redis分布式锁系列

1.压力测试出的内存泄漏及解决&#xff08;可跳过&#xff09; 使用jmeter对查询产品分类列表接口进行压力测试&#xff0c;出现了堆外内存溢出异常。 我们设置的虚拟机堆内存100m&#xff0c;并不是堆外内存100m 产生堆外内存溢出&#xff1a;OutOfDirectMemoryError 原因是…

某大厂面试题:说一说Java、Spring、Dubbo三者SPI机制的原理和区别

大家好&#xff0c;我是三友~~ 今天来跟大家聊一聊Java、Spring、Dubbo三者SPI机制的原理和区别。 其实我之前写过一篇类似的文章&#xff0c;但是这篇文章主要是剖析dubbo的SPI机制的源码&#xff0c;中间只是简单地介绍了一下Java、Spring的SPI机制&#xff0c;并没有进行深…

SQL——数据查询DQL

基本语句、时间查询&#xff08;当天、本周&#xff0c;本月&#xff0c;上一个月&#xff0c;近半年的数据&#xff09;。 目录 1 查询语句基本结构 2 where 子句 3 条件关系运算符 4 条件逻辑运算符 5 like 子句 6 计算列 7 as 字段取别名 8 distinct 清除重复行 9 …

linux mysql

安装 下载包 wget https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.31-1.el8.x86_64.rpm-bundle.tar解压 tar -zxvf mysql-8.0.31-1.el8.x86_64.rpm-bundle.tar -C /usr/local/mysql安装openssl-devel插件 yum install openssl-devel安装rpm包 使用rpm -ivh安装图中r…

【Unity项目实战】从零手戳一个背包系统

首先我们下载我们的人物和背景资源,因为主要是背包系统,所以人物的移动和场景的搭建这里我们就不多讲了,我这里直接提供基础项目源码给大家去使用就行 基础项目下载地址: 链接: https://pan.baidu.com/s/1o7_RW_QQ1rrAbDzT69ApRw 提取码: 8s95 顺带说一下,这里用到了uni…

AttributeError: module transformers has no attribute LLaMATokenizer解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

AES加密

来源&#xff1a;链接: b站up主可厉害的土豆 &#xff08;据评论区说图片中有计算错误&#xff0c;但是过程是对的。只是了解过程问题不大&#xff0c;专门研究这一块的话自己可以看视频算一下&#xff09; 准备 首先&#xff0c;明文是固定长度 16字节 128位。 密钥长度可以…

TCP协议一

TCP数据报格式 TCP通信时序 下图是一次TCP通讯的时序图。TCP连接建立断开。包含大家熟知的三次握手和四次握手。 在这个例子中&#xff0c;首先客户端主动发起连接、发送请求&#xff0c;然后服务器端响应请求&#xff0c;然后客户端主动关闭连接。两条竖线表示通讯的两端&…

houjie-cpp面向对象

houjie 面向对象 面向对象&#xff08;上&#xff09; const 在一个函数后面放const&#xff0c;这个只能修饰成员函数&#xff0c;告诉编译器这个成员函数不会改数据 const还是属于函数签名的一部分。 引用计数&#xff1a;涉及到共享的东东&#xff0c;然后当某个修改的时候&…

Mysql的学习与巩固:一条SQL查询语句是如何执行的?

前提 我们经常说&#xff0c;看一个事儿千万不要直接陷入细节里&#xff0c;你应该先鸟瞰其全貌&#xff0c;这样能够帮助你从高维度理解问题。同样&#xff0c;对于MySQL的学习也是这样。平时我们使用数据库&#xff0c;看到的通常都是一个整体。比如&#xff0c;你有个最简单…

【Paper】2019_Resilient Consensus Through Asynchronous Event-based Communication

Wang Y, Ishii H. Resilient consensus through asynchronous event-based communication[C]//2019 American Control Conference (ACC). IEEE, 2019: 1842-1847. 文章目录I. INTRODUCTIONII. EVENT-BASED RESILIENT CONSENSUS PROBLEMA. Preliminaries on graphsB. Event-base…

基于Java+ SpringBoot+Vue 的网上图书商城管理系统(毕业设计,附源码,教程)

您好&#xff0c;我是程序员徐师兄&#xff0c;今天为大家带来的是 基于Java SpringBootVue 的网上图书商城管理系统&#xff08;毕业设计&#xff0c;附源码&#xff0c;教程&#xff09;。 &#x1f601; 1.Java 毕业设计专栏&#xff0c;毕业季咱们不慌忙&#xff0c;几百款…

电脑桌面图标间距突然变大怎么恢复

1. WindowsR打开 > 输入regedit 按住WindowsR打开运行&#xff0c;输入regedit并点击确定。 2. 双击Control Panel 双击展开HKEY_CURRENT_USER&#xff0c;双击展开Control Panel&#xff0c;双击展开Desktop。 3. 更改间距 点击打开WindowMetrics&#xff0c; 双击打开…

两年外包生涯,给我后面入职字节跳动奠定了基础.....

我是一位软件测试工程师。从大学毕业后&#xff0c;我进入了一家外包公司&#xff0c;在那里工作了两年时间。虽然我在公司中得到了不少锻炼和经验&#xff0c;但是我一直渴望能够进入一家更加专业的公司&#xff0c;接触更高端、更有挑战性的项目。 于是&#xff0c;我开始主…

Keil 4 安装教程及简单使用【嵌入式系统】

Keil 4 安装教程及简单使用【嵌入式系统】前言推荐说明Keil 4 for Arm安装教程1.安装MDK2.激活mdkkeil 4 for arm 的简单使用1建立新工程2在工程下创建新文件3.设置工程属性4.中文注释5.编辑代码6.build7.debug8. 调试窗口简介keil 4 for C51安装教程1.前期准备2.开始keil4 for…

记录-VueJs中如何使用Teleport组件

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 在DOM结构相对比较复杂,层级嵌套比较深的组件内,需要根据相对应的模块业务处理一些逻辑,该逻辑属于当前组件 但是从整个页面应用的视图上看,它在DOM中应该被渲染在整个vue应用外部的其他地方,不能影响…

[架构之路-159]-《软考-系统分析师》-10-系统分析-6-现有业务流程分析, 系统分析最核心的任务

目录 第 10章 现有系统 分 析 1 0 . 6 现有业务流程分析 10.6.1 业务流程分析槪述 1 . 业务流程分析的步骤 2 . 业务流程分析的方法 10.6.2 业务-流程图TFD 1. T F D 的基本符号 2. TFD的绘制 10.6.3 业务 - 活动图 10.6.4 业务流程建模BPM 1. B P M 概述 2 . 标杆…

计算机视觉基础__图像特征

计算机视觉基础__图像特征 本篇目录&#xff1a; 一、前言 二、位图和矢量图概念 三、图像的颜色特征 四、RGB 颜色空间 五、HSV 颜色空间 六、HLS 颜色空间 七、实例代码 八、参考资料 一、前言 传统图像处理&#xff0c;需要找出图片中的关键特征&#xff0c;然后对这…
最新文章