顺序表 --- C语言实现

news2024/12/27 13:49:38

 

目录

1.线性表

2.顺序表

2.1 概念和结构

2.2 接口实现

2.3 数组相关面试题

2.4 顺序表的问题及思考


1.线性表

什么是线性表 :

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

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

2.顺序表

2.1 概念和结构

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

顺序表一般可以分为:

  1. 静态顺序表,使用定长数组存储元素。
  2. 动态顺序表:使用动态开辟的数组存储。

 1.静态顺序表的定义

#define N 7 //顺序表的大小
typedef int SLDataType;

typedef struct SeqList
{
    SLDataType array[N];    //定长数组,顺序表只能存储N个元素
    int size;               //有效元素个数
}SeqList;

2.动态顺序表的定义

typedef int SLDatatype;

typedef struct SeqList
{
	SLDatatype* a; //指向动态开辟的数组,空间不够可以扩容
	int size;      //有效数据个数
	int capacity;  //容量空间大小
}SeqList;

2.2 接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。

所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

头文件 :

typedef int SLDatatype;

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

//初始化
void SeqListInit(SeqList* ps);
//释放
void SeqListDestroy(SeqList* ps);
//打印
void SeListPrint(SeqList* ps);
//头插法
void SLPushfront(SeqList* ps, SLDatatype x);
//尾插法
void SLPushback(SeqList* ps, SLDatatype x);
//头删
void SLPopfront(SeqList* ps);
//尾删
void SLPopback(SeqList* ps);
//顺序表查找
int SeqListFind(SeqList* ps, SLDatatype x);
//在顺序表pos位置插入x
void SeqListInsert(SeqList* ps,int pos, SLDatatype x);
//删除顺序表pos位置的值
void SeqListErase(SeqList* ps,int pos);
//修改顺序表pos位置的值
void SeqListMidefy(SeqList* ps, int pos, SLDatatype x);

 函数的实现:

//初始化
void SeqListInit(SeqList* ps)
{
	assert(ps);
	ps->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (ps->a == 0)
	{
		perror("malloc fail");
		return;
	}
	ps->size = 0;
	ps->capacity = 4;
}
//释放
void SeqListDestroy(SeqList* ps)
{
	assert(ps);
	ps->size = 0;
	ps->capacity = 0;
	free(ps->a);
	ps->a = NULL;
}
//打印
void SeListPrint(SeqList* ps)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

//检查容量
int CheckCapacity(SeqList* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		SLDatatype* ptr = (SLDatatype*)realloc(ps->a, sizeof(SLDatatype) * ps->capacity * 2);
		if (ptr == NULL)
		{
			perror("realloc fail");
			return 0;
		}
		else
		{
			ps->a = ptr;
			ps->capacity *= 2;
		}
	}
	return 1;
}

//头插法
void SLPushfront(SeqList* ps, SLDatatype x)
{
	assert(ps);
	if (CheckCapacity(ps) == 0)
	{
		return;
	}

	int end = ps->size;
	while (end > 0)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[0] = x;
	ps->size++;
	
}
//尾插法
void SLPushback(SeqList* ps, SLDatatype x)
{
	assert(ps);
	if (CheckCapacity(ps) == 0)
	{
		return;
	}
	ps->a[ps->size] = x;
	ps->size++;
}
//头删
void SLPopfront(SeqList* ps)
{
	assert(ps);
	assert(ps->size > 0);
	int start = 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		start++;
	}
	ps->size--;
}
//尾删
void SLPopback(SeqList* ps)
{
	assert(ps);
	assert(ps->size > 0);
	ps->size--;
}
//顺序表查找
int SeqListFind(SeqList* ps, SLDatatype x)
{
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return -1;
}
//在顺序表pos位置插入x
void SeqListInsert(SeqList* ps, int pos, SLDatatype x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	if (CheckCapacity(ps) == 0)
	{
		return;
	}
	int end = ps->size;
	while (end > pos)
	{
		ps->a[end] = ps->a[end - 1];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}
//删除顺序表pos位置的值
void SeqListErase(SeqList* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//已经包含 ps->size > 0
	int start = pos + 1;
	while (start < ps->size)
	{
		ps->a[start - 1] = ps->a[start];
		start++;
	}
	ps->size--;
}
//修改顺序表pos位置的值
void SeqListMidefy(SeqList* ps, int pos, SLDatatype x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//已经包含 ps->size > 0
	ps->a[pos] = x;
}

2.3 数组相关面试题

  1. 原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。OJ链接
  2. 删除排序数组中的重复项。OJ链接
  3. 合并两个有序数组。ОJ链接

2.4 顺序表的问题及思考

问题:

1.中间/头部的插入删除,时间复杂度为O(N)

2.增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3.增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考:如何解决以上问题呢?可以通过看下一篇文章链表来解决。

本篇结束:

 

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

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

相关文章

Vue3 概述

文章目录 Vue3 概述概述Vue3对比Vue2优势使用create-vue创建项目概述创建项目目录结构 使用vue-cli创建项目概述创建项目目录结构 Vue3 概述 概述 Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript…

自定义指令directives:防抖,节流,element-ui的无限滚动在el-table上使用的封装

vue官网对于自定义指令的介绍 添加链接描述 除了核心功能默认内置的指令 (v-model 和 v-show)&#xff0c;Vue 也允许注册自定义指令。注意&#xff0c;在 Vue2.0 中&#xff0c;代码复用和抽象的主要形式是组件。然而&#xff0c;有的情况下&#xff0c;你仍然需要对普通 DOM…

分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)

目录 可靠消息最终一致性分布式事务实现_RocketMQ事务消息 可靠消息最终一致性分布式事务实战_案列业务介绍 数据库表设计 可靠消息最终一致性分布式事务实战_Docker安装 RocketMQ 部署RocketMQ的管理工具 可靠消息最终一致性分布式事务实战_实现订单微服务 可靠消息最终一…

分层解耦-IOCDI-DI详解

目录 Bean注入 小结 依赖注入的注解 Resource和Autowired区别 Bean注入 Autowired注解&#xff0c;默认是按照类型进行依赖注入&#xff0c;如果存在多个相同类型的bean就会报错 解决方案 Primary&#xff08;设置bean的优先级&#xff09; Qualifier&#xff08;通过bean…

简单版本视频播放服务器V1

一直想做个家用版本的视频播放器&#xff0c;通过这个可以实现简单的电脑&#xff0c;通过浏览器就是可以访问电脑里面的视频&#xff0c;通过手机&#xff0c;平板等都是可以访问自己的视频服务了 后端代码&#xff1a; package mainimport ("fmt""io/iouti…

2023年7月13日 星期四 Linux驱动作业

1.使用platform驱动实现代码实现如下要求 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变(按键中断) 例如number0 按下按键number1再次按下按键number0d.在按下按键的时候需要同时将1ed1的状态取反 t e.驱动…

Tik Tok你不知道的那些知识?

TikTok是一款短视频社交平台&#xff0c;由中国公司字节跳动&#xff08;ByteDance&#xff09;开发和运营。它让用户可以通过手机拍摄、编辑和分享15秒至60秒的短视频&#xff0c;涵盖了各种内容&#xff0c;包括音乐、舞蹈、喜剧、唱歌、游戏等。TikTok以其简单易用和丰富多样…

Meteor code must always run within a Fiber 报错解决办法

报错&#xff1a; 这样的写法会出现这个报错 大概的意思就是说&#xff0c;目前你这个函数不是运行在meteor的环境中&#xff0c;所以要使用Meteor.bindEnvironment&#xff0c;来改变函数运行的上下文 解决办法&#xff1a;

87. 把字符串转换成整数

目录 链接&#xff1a; 题目&#xff1a; 思路&#xff1a; 代码&#xff1a; 图片&#xff1a; 链接&#xff1a; 原题链接 题目&#xff1a; 请你写一个函数 StrToInt&#xff0c;实现把字符串转换成整数这个功能。 当然&#xff0c;不能使用 atoi 或者其他类似的库函数…

摆脱基础设施束缚,亚马逊云科技提出生成式AI方法论

“未来近在咫尺&#xff0c;只不过时隐时现 (The future is here, its just not evenly distributed yet.)”--亚马逊云科技全球产品副总裁Matt Wood博士引用“赛博朋克之父” William Gibson 的一句名言来表达生成式AI的发展现状。 自去年底ChatGPT惊艳众人开始&#xff0c;这…

云原生高性能API网关,选Apache APISIX还是Nginx Plus

文章首发地址 Apache APISIX 对比 Nginx Plus APISIX 和 Nginx Plus 都是高性能的 API 网关&#xff0c;具有类似的特点&#xff0c;如可扩展性、插件化、负载均衡、反向代理等。下面对 APISIX 和 Nginx Plus 进行对比&#xff1a; 开源授权&#xff1a;APISIX 是 Apache 开…

Java阶段五Day05

Java阶段五Day05 文章目录 Java阶段五Day05问题解析无法启动Naocs Nacos服务注册发现Nacos运行架构nacos-server是一个服务进程 配置注册服务端客户端csmall-for-jsd-business-adapter 整合nacos-clientyaml详细配置注册信息在nacos中的内存状态多实例注册服务抓取&#xff08;…

五大引擎全新升级!轻流 5.0 正式发布

轻流的5.0版本&#xff0c;一个“陪伴企业成长的一站式开发平台”&#xff0c;它将更加灵活、更加开放&#xff0c;同时更加低门槛。 ——轻流联合创始人&CPO 严琦东 7月6日&#xff0c;在一年一度的无代码无边界 202376Day 轻流无代码探索者大会上&#xff0c;轻流联合创…

SpringMVC实现对页面的访问和跳转~

初识MVC: MVC是一种软件架构的思想&#xff0c;将软件按照模型&#xff0c;视图&#xff0c;控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean,作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体类Bean:专门存储业务数据的&…

Java 中线程相关的各种锁

一、Java对象与锁 1、对象结构 2、对象头的 Mark Word 二、锁介绍 1、概念和种类 1、乐观锁 不加锁&#xff0c;在使用数据时判断数据是不是最新。常用CAS算法实现 2、自旋锁 与 适应性自旋锁 两者并不是锁&#xff0c;而是锁提供的处理方式。 自旋锁&#xff08;JDK1.4&a…

Sentinel 熔断与限流

文章目录 1 是什么&#xff1f;2 特征3 特性4 与Hystrix的区别5 两个部分6 应用6.1 依赖6.2 配置文件 7 流量配置规则7.1 直接&#xff08;默认&#xff09;7.2 关联7.3 Warm Up 预热7.4 排队等待 8 熔断降级8.1 概述RT(平均响应时间&#xff0c;秒级)异常比列(秒级)异常数(分钟…

python-cv2模块安装

1.自动安装 如果网络环境好&#xff1a; pip install opencv-python2.卸载与安装指定版本 卸载opencv pip uninstall opencv-python安装指定版本的cv 指定版本为&#xff1a;4.5.4.60 pip install opencv-python 4.5.4.603.下载安装包安装 从官网下载正确安装包安装&#x…

【Linux工具】编译器、调式器、项目自动化构建工具以及git的使用2(make/makefile和git的基本使用)

【Linux工具】编译器、调式器、项目自动化构建工具以及git的使用2&#xff08;make/makefile和git的基本使用&#xff09; 目录 【Linux工具】编译器、调式器、项目自动化构建工具以及git的使用2&#xff08;make/makefile和git的基本使用&#xff09;背景make和makefile的用法…

Proxy-Reflect使用详解

1 监听对象的操作 2 Proxy类基本使用 3 Proxy常见捕获器 4 Reflect介绍和作用 5 Reflect的基本使用 6 Reflect的receiver Proxy-监听对象属性的操作(ES5) 通过es5的defineProperty来给对象中的某个参数添加修改和获取时的响应式。 单独设置defineProperty是只能一次设置一…

AppStorage, OnboardingView 的示例

1. AppStorage 数据简单存储的实现 /// 应用程序数据简单存储 struct AppStorageBootcamp: View {//State var currentUserName: String?AppStorage("name") var currentUserName: String?var body: some View {VStack(spacing: 20) {Text(currentUserName ?? &…