【数据结构】线性表之顺序表

news2024/12/27 18:07:40

目录

  • 一、线性表的定义
  • 二、顺序表
    • 1. 顺序表的定义
    • 2. 顺序表的结构
      • 2.1 静态顺序表
      • 2.2 动态顺序表
    • 3. 动态顺序表的接口实现
      • 3.1 顺序表的接口
      • 3.2 接口的实现
  • 三、顺序表总结
    • 1. 动态顺序表的优点
    • 2. 动态顺序表的缺点
  • 结尾

一、线性表的定义

线性表是 n (n >= 0) 个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的线性表在物理上存储时,通常以数组和链式结构的形式存储。

数组形式

在这里插入图片描述

链表形式

在这里插入图片描述

二、顺序表

1. 顺序表的定义

顺序表是一种线性数据结构,通过连续的内存空间存储元素,可以随机访问任何位置的元素。它支持在常量时间内进行插入、删除和访问操作,但在插入或删除元素时可能需要移动后续元素,导致时间复杂度为O(n)

2. 顺序表的结构

2.1 静态顺序表

静态顺序表使用定长数组,当数组存储满后则不能再进行存储。
在这里插入图片描述

2.2 动态顺序表

动态顺序表使用动态申请的数组进行存储,当顺序表被存满后,会自动扩大容量。

在这里插入图片描述

在这里插入图片描述

3. 动态顺序表的接口实现

3.1 顺序表的接口

typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;
	int size;
	int capacity;
}SeqList;

// 对数据的管理:增删查改 

//顺序表的初始化
void SeqListInit(SeqList* ps);
//顺序表的销毁
void SeqListDestroy(SeqList* ps);

//顺序表的打印
void SeqListPrint(SeqList* ps);
//顺序表的尾插
void SeqListPushBack(SeqList* ps, SLDateType x);
//顺序表的头插
void SeqListPushFront(SeqList* ps, SLDateType x);
//顺序表的的头删
void SeqListPopFront(SeqList* ps);
//顺序表的尾删
void SeqListPopBack(SeqList* ps);

// 顺序表查找
int SeqListFind(SeqList* ps, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SeqList* ps, int pos);

3.2 接口的实现

void SeqListInit(SeqList* ps)
{
	//动态申请十个 SLDateType 类型大小的空间
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 10);
	//判断是否开辟成功
	if (ps->a == NULL)
	{
		perror("malloc");
		return;
	}  
	ps->size = 0;        //顺序表初始化,顺序表内无数据,则赋值为 0
	ps->capacity = 10;   //容量为动态申请的元素个数
}


void SeqListDestroy(SeqList* ps)
{
	//将动态申请的空间释放
	free(ps->a);
	ps->a = NULL;
}

int CheckSeqList(SeqList* ps)
{
	//检查顺序表是否被填满
	if (ps->capacity == ps->size)
	{
		//若填满则将动态申请的内存扩大为原来的两倍
		SLDateType* tmp = (SLDateType*)realloc(ps->a, sizeof(SLDateType) * (ps->capacity * 2));
		//定义一个变量接收扩大后返回空间的首地址
		//目的:若开辟失败也不会改变原来的内存
		if (tmp == NULL)
		{
			perror("realloc");
			return 0;
		}
		ps->a = tmp;
		//将容量变成原来的两倍
		ps->capacity *= 2;
	}
	return 1;
}


void SeqListPushBack(SeqList* ps, SLDateType x)
{
	//判断顺序表是否为满,未满则进行下面的步骤
	//若满了,则先扩容,再进行下面的步骤
	if (CheckSeqList(ps) == 0)
	{
		return;
	}
	
	//将需要尾插的数据放在下标为size的数组中
	ps->a[ps->size] = x;
	//存储的元素加一
	ps->size++;
}

void SeqListPrint(SeqList* ps)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
}

void SeqListPushFront(SeqList* ps, SLDateType x)
{
	//判断顺序表是否为满,未满则进行下面的步骤
	//若满了,则先扩容,再进行下面的步骤
	if (CheckSeqList(ps) == 0)
	{
		return;
	}

	//下面省略的代码是没有用随机插入函数实现的
	/*int i = 0;
	for (i = ps->size - 1; i >= 0; i--)
	{
		//将所有的元素向后移动一位
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[0] = x;   //将需要插入的元素放在首元素的位置
	ps->size++;*/	//存储元素个数加一
	
	//下面省略的代码是没有用随机插入函数实现的,并使用memmove函数移动数组
	
	/*memmove(ps->a + 1, ps->a, sizeof(SLDateType) * ps->size);
	ps->a[0] = x;
	ps->size++;*/
	
	//该代码是使用随机插入函数实现的
	SeqListInsert(ps, 0, x);
	
}


void SeqListPopFront(SeqList* ps)
{
	//下面省略的代码是没有用随机删除函数实现的
	//断言:顺序表为空不能删除
	//assert(ps->size != 0);
	/*int i = 0;
	//将首元素后面的元素全部向前移动一位
	for (i = 0; i < ps->size - 1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;*/  //存储元素个数减一

	//下面省略的代码是没有用随机删除函数实现的,并使用memmove函数移动数组
	/*memmove(ps->a, ps->a + 1, sizeof(SLDateType) * (ps->size - 1));
	ps->size--;*/ 
	
	//该代码是使用随机删除函数实现的
	SeqListErase(ps, 0);
}

void SeqListPopBack(SeqList* ps)
{
	//下面省略的代码是没有用随机删除函数实现的
	
	//断言:顺序表为空不能删除
	/*assert(ps->size != 0);
	ps->size--;*/ //存储元素个数减一
	
	//该代码是使用随机删除函数实现的
	SeqListErase(ps , ps ->size - 1);
}


int SeqListFind(SeqList* ps, SLDateType x)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}


void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
	int i = 0;
	//需要插入的位置不能在size下标元素的后面
	//原因是size - 1 下标中的元素是最后一个元素
	assert(ps->size >= pos);
	/*for (i = ps->size - 1; i >= pos; i--)
	{
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;*/

	memmove(ps->a + pos + 1, ps->a + pos, sizeof(SLDateType)*(ps->size - pos));
	ps->a[pos] = x;
	ps->size++;
}

void SeqListErase(SeqList* ps, int pos)
{
	//顺序表不能为空
	assert(ps->size != 0);
	int i = 0;
	//将需要删除元素的后面的元素全部向前移动一位
	for (i = pos; i < ps->size - 1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

三、顺序表总结

1. 动态顺序表的优点

(1)可以根据需要动态地分配内存,灵活性更高。
(2)可以避免静态数组可能出现的内存浪费问题。
(3)由于内存空间是动态分配的,因此可以处理数据量不确定或者变化的情况。

2. 动态顺序表的缺点

(1)动态内存分配比静态内存分配要慢一些,会增加程序的运行时间。
(2)需要手动管理内存,包括申请和释放,容易出现内存泄漏和内存碎片等问题。
(3)难以预测、控制内存的使用情况,容易出现因为内存不足而导致程序崩溃的情况

结尾

如果有什么建议和疑问,或是有什么错误,希望大家能够提一下。
希望大家以后也能和我一起进步!!
如果这篇文章对你有用的话,希望能给我一个小小的赞!

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

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

相关文章

日志服务器的搭建

日志服务器 在centos7系统中&#xff0c;默认的日志系统是rsyslog&#xff0c;它是一类unix系统上使用的开源工具&#xff0c;用于在ip网络中转发日志信息&#xff0c;rsyslog采用模块化设计&#xff0c;是syslog的替代品。 rsyslog特点 实现了基本的syslog协议 直接兼容syslo…

linkindList源码分析

前言 LinkedList &#xff0c;基于节点实现的双向链表的 List &#xff0c;每个节点都指向前一个和后一个节点从而形成链表。 LinkedList集合同时具有List集合和Queue集合的基本特征 类图 如下 1 个接口是少于 ArrayList 的&#xff1a; java.util.RandomAccess 接口&#xff…

Sui正式推出学术研究奖计划

欢迎研究人员和学者提交第一轮Sui学术研究奖的资金申请。 Sui基金会诚邀来自世界各地机构的研究人员和学者申请第一轮Sui学术研究奖。申请按提交顺序排序&#xff0c;每个季度公布一次。 跨学科研究对于深入理解Web3及其改变世界的潜力起着关键性的作用。Sui基金会推出的学术…

【定义函数与常用函数】------- PYTHON基础7

内容目录 一、 定义函数二、Python常用函数介绍min() ; max()sum() ; sum(x, start 0)type()str()sorted()help() 一、 定义函数 定义了一个计算三角形面积的函数,然后调用 def triangle_area(w, h):area w * h/2print(底边长为&#xff1a; , w, &#xff0c;高为&#xff…

Redis-2.1-架构综述

1 Redis组件模型 Redis 组件的系统架构如图所示&#xff0c;主要包括事件处理、数据存储及管理、用于系统扩展的主从复制/集群管理&#xff0c;以及为插件化功能扩展的 Module System 模块。 Redis的客户端与服务端的交互过程如下所示&#xff1a; 1.1 事件处理机制 Redis 中的…

linux中wait与waitpid函数使用场景及扩展

一般运用这两个函数&#xff0c;是在父进程等待子进程退出的过程中 区别:wait使调用者阻塞&#xff0c;waitpid有一个选项&#xff0c;可以使调用者不阻塞 status参数是一个整型数指针 非空&#xff1a;子进程退出状态放在它所指向的地址中。 空&#xff1a;不关心退出状态 …

计算机视觉的深度学习 Lecture2 笔记 EECS 498.008

Lecture2 498_FA2019_lecture02 KNN可视化 没有测试集、只有测试集都是很糟糕的。要有验证集&#xff0c;验证集只使用一次、且在训练了足够时间之后。 不过这样可能会导致最后才发现算法的效果不好。 更好的解决思路&#xff1a; [外链图片转存失败,源站可能有防盗链机制,建…

算法(一)—— 回溯

文章目录 前言1 77 组合2 77 组合优化 前言 1、回溯法解决的问题都可以抽象为树形结构&#xff08;N叉树&#xff09;&#xff0c;使用树形结构来理解回溯。 2、回溯法解决的都是在集合中递归查找子集&#xff0c;集合的大小就构成了树的宽度&#xff0c;递归的深度&#xff…

【分支与循环】------- PYTHON基础6

内容目录 一、分支结构分支结构 – 条件语句 if分支结构 – 条件语句 if…else分支结构 – 条件语句 if…elif…else 二、循环结构循环结构 – 初识 while 循环循环结构 – while 无限循环 一、分支结构 分支结构 – 条件语句 if score input(请输入成绩&#xff1a;) #inpu…

C++指针详解

指针 目录 内存变量指针变量 对指针进行赋值指针占用的内存 使用指针 指针用于函数参数用const修饰指针 void关键字C内存模型动态分配内存new 和 delete二级指针空指针野指针一位数组和指针 数组的地址数组的本质数组名不一定会被解释为地址一维数组作为函数参数用new动态创建…

学习Maven Web 应用

Maven Web 应用 本章节我们将学习如何使用版本控制系统 Maven 来管理一个基于 web 的项目&#xff0c;如何创建、构建、部署已经运行一个 web 应用。 创建 Web 应用 我们可以使用 maven-archetype-webapp 插件来创建一个简单的 Java web 应用。 打开命令控制台&#xff0c;…

bootstrap-fileinput文件上传、回显使用详解

文件上传bootstrap-fileinput使用详解 一、增加页面的文件上传&#xff08;一&#xff09;bootstrap-fileinput文件上传功能1.先引入js依赖2.在html上面写入文件框 &#xff08;二&#xff09;根据若依给出的示例引用和改进&#xff08;三&#xff09;根据uploadUrl进行上传&am…

博客管理系统--显示、退出、发布功能

6&#xff1a;显示用户信息7&#xff1a;退出登录总结博客管理系统 6&#xff1a;显示用户信息 这部分&#xff1b;希望是根据用户来显示&#xff1b;如果是博客列表页则显示登录用户的信息&#xff1b;如果是博客详情页则显示作者的信息。 1&#xff1a;前后端交互接口约定 …

如何压缩pdf文件大小?四种方法随意选择

如何压缩pdf文件大小&#xff1f;PDF文件格式由于其跨平台性&#xff0c;易于浏览、打印和传输等特点&#xff0c;在现代社会中广泛应用于各个领域。然而&#xff0c;随着PDF文件越来越大&#xff0c;传输及存储所需的时间也会变得越来越长&#xff0c;从而降低了工作效率。在这…

简单记忆clarke和park坐标变换

简单记忆clarke和park坐标变换 简介 想用简单的办法把这些变换矩阵写出来&#xff0c;需要的时候可以使用&#xff0c;不用再去翻书&#xff08;当然完全记住还是更快一些&#xff09;。只是自己用来记忆这些变换的方法。 具体可以参考&#xff1a;手撕系列&#xff08;2&am…

【Redis】实现及优化分布式锁:实现、解决误删锁问题以及lua脚本确保redis操作原子性

目录 一、概念及不同分布式锁实现的对比 1、概念 2、特征 3、不同分布式锁实现的对比 二、Redis实现分布式锁的思路 1、获取锁思路 2、释放锁思路 三、代码实现分布式锁 1、准备 2、获取锁 2、释放锁 四、分布式锁的误删锁问题 1、问题 2、原因 五、误删锁的解决…

分布式配置中心

一、Config概述 Spring Cloud Config 解决了在分布式场景下多环境配置文件的管理和维护 好处&#xff1a; 集中管理配置文件 不同环境不同配置&#xff0c;动态化的配置更新 配置信息改变时&#xff0c;不需要重启即可更新配置信息到服务 二、Config 快速入门 1、使用git…

5.10-5.11总结

我教的课中 课程双击事件&#xff0c;跳转到课程界面 输入学生姓名和学号&#xff0c;添加学生 加载学生名单&#xff0c;双击学生&#xff0c;弹出学生资料&#xff0c;并且可以删除学生 但删除学生还有bug。

LeetCode - 1552 两球之间的磁力

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 1552. 两球之间的磁力 - 力扣&#xff08;LeetCode&#xff09; 题目描述 在代号为 C-137 的地球上&#xff0c;Rick 发现如果他将两个球放在他新发明的篮子里&#xff0c;它们之间会形成特殊形式的磁力。…

二维各向同性介质弹性波数值模拟(交错网格有限差分法)

一、一阶速度-应力弹性波方程 在二维各向同介质xoz平面内&#xff0c;假定体力为0。 从上面方程当中&#xff0c;我们为了得到各点的应力和速度值&#xff0c;就需要得到关于对时间t和空间x&#xff0c;z的偏导。 二、时间上的2M阶差分 由Taylor公式得 三、空间2N阶近似差分…