数据结构:顺序表的增、删,查、改实现

news2024/9/21 20:37:20

1.概念 

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

 

2.分类 

顺序表一般可以分为:

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

 这样会造成空间给多了浪费,给少了不够用。于是我们使用一种动态开辟的数组储存

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

 

3.实现

3.1 构建一个结构体

typedef int SLDatatype;
typedef struct SeqList
{
	SLDatatype* a;
	int size;       // 存储的有效数据的个数
	int capacity;   // 容量
}SL;

3.2顺序表初始化和销毁 

//初始化
void SLInit(SL* psl)
{
	psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (psl->a == NULL)
	{
		perror("malloc fail");
		return;
	}

	psl->capacity = 4;
	psl->size = 0;
}
//销毁
void SLDestroy(SL* psl)
{
	free(psl->a);
	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;
}

3.3顺序表的打印 

//打印
void SLprintf(SL* psl)
{
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
	printf("Size:%d\n", psl->size);
}

3.4顺序表任意位置插入

//是否要增容
void SLCheck(SL* psl)
{
	if (psl->size == psl->capacity)
	{
		SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		psl->a = tmp;
		psl->capacity *= 2;
	}
}
//任意位置插入
void SLInsert(SL* psl, int pos, SLDatatype x)
{
    //检查是否要增容
	SLCheck(psl);
	int end = 0;
	end = psl->size - 1;
	while (end >= pos)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[pos] = x;
	psl->size++;

}

 

 3.5顺序表任意位置删除

//任意位置删除
void SLErase(SL* psl, int pos)
{
	int start = pos + 1;
	while (start < psl->size)
	{
        //相当与直接覆盖
		psl->a[start - 1] = psl->a[start];
		++start;
	}

	psl->size--;
}

3.6顺序表的查找 

//查找并返回下标
int SLFind(SL* psl, SLDatatype x)
{
	assert(psl);
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		if (x == psl->a[i])
		{
			return i;
		}
	}
}

3.7顺序表的修改 

//pos是要修改的下标,x是要修改的数字
void SLModify(SL* psl, int pos, SLDatatype x)
{
	assert(psl);

	assert(0 <= pos && pos < psl->size);

	psl->a[pos] = x;
}

4.完整的代码 

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

typedef int SLDatatype;
typedef struct SeqList
{
	SLDatatype* a;
	int size;       // 存储的有效数据的个数
	int capacity;   // 容量
}SL;


//顺序表初始化
void SLInit(SL* psl);

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

//顺序表初打印
void SLprintf(SL* psl);

//检查空间,如果满了则进行增容
void SLCheck(SL* psl);

//顺序表查找
int SLFind(SL* psl, SLDatatype x);

//顺序表在POS中插入一个数
void SLInsert(SL* psl, int pos, SLDatatype x);

//顺序表在POS中删除一个数
void SLErase(SL* psl, int pos);

//顺序表修改
void SLModify(SL* psl, int pos, SLDatatype x)

上面是SeqList.h

 SeqList.c

#include"SeqList.h"
//˳ʼ
void SLInit(SL* psl)
{
	psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (psl->a == NULL)
	{
		perror("malloc fail");
		return;
	}

	psl->capacity = 4;
	psl->size = 0;
}
//˳
void SLDestroy(SL* psl)
{
	free(psl->a);
	psl->a = NULL;
	psl->size = 0;
	psl->capacity = 0;
}

void SLprintf(SL* psl)
{
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		printf("%d ", psl->a[i]);
	}
	printf("\n");
	printf("Size:%d\n", psl->size);
}

void SLCheck(SL* psl)
{
	if (psl->size == psl->capacity)
	{
		SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		psl->a = tmp;
		psl->capacity *= 2;
	}
}


int SLFind(SL* psl, SLDatatype x)
{
	assert(psl);
	int i = 0;
	for (i = 0; i < psl->size; i++)
	{
		if (x == psl->a[i])
		{
			return i;
		}
	}
}

void SLInsert(SL* psl, int pos, SLDatatype x)
{
	SLCheck(psl);
	int end = 0;
	end = psl->size - 1;
	while (end >= pos)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[pos] = x;
	psl->size++;

}

void SLErase(SL* psl, int pos)
{
	int start = pos + 1;
	while (start < psl->size)
	{
		psl->a[start - 1] = psl->a[start];
		++start;
	}

	psl->size--;
}

void SLModify(SL* psl, int pos, SLDatatype x)
{
	assert(psl);

	assert(0 <= pos && pos < psl->size);

	psl->a[pos] = x;
}

5.总结 

上面便是我今天讲的全部内容,还有许多不足希望多多指正

下面给大家个问题

1. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
2. 增容一般是呈 2 倍的增长,势必会有一定的空间浪费。例如当前容量为 100 ,满了以后增容到 200,我们再继续插入了 5 个数据,后面没有数据插入了,那么就浪费了 95 个数据空间。
如何减少空间复杂度呢?

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

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

相关文章

ThreadLocal初探

一、ThreadLocal介绍 一、官方介绍 从Java官方文档中的描述&#xff1a;ThreadLocal类用来提供线程内部的局部变量&#xff0c;这种变量在多线程环境下访问&#xff08;通过get和set方法访问&#xff09;时&#xff0c;能够保证各个线程的变量相对独立于其他线程内的变量。Thr…

apple pencil必须要买吗?性价比平替电容笔排行榜

要知道&#xff0c;真正的苹果原装Pencil&#xff0c;价格实在是太贵了&#xff0c;普通的消费者根本买不起。所以&#xff0c;有没有可能出现一种平替的、功能一模一样的、与苹果Pencil一样的电容笔呢&#xff1f;这倒也是。国产的平替笔和苹果Pencil的笔相比&#xff0c;并没…

Wireless-Sensor-Network-master_WSN_无线传感网络(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 近年来&#xff0c;随着对等网络、云计算和网格计算等分布式环境的发展&#xff0c;无线传感器网络&#xff08;WSN&#xff0…

10分钟吃透,python操作mysql数据库的增、删、改、查

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

聊聊汽车OTA测试技术方案

汽车OTA已成为时下热门话题&#xff0c;由于OTA的升级可能会带来一定的风险&#xff0c;针对OTA的测试就尤为重要。本文我们主要通过介绍OTA的发展背景、汽车OTA测试的必要性以及汽车OTA测试内容&#xff0c;为大家分享一套成熟的OTA测试方案。 什么是OTA OTA&#xff08;Over-…

以最大速度将数据迁移至AWS S3存储

数据上云&#xff0c;已经成为企业数据管理发展的必然趋势。 对于企业而言&#xff0c;数据上云“常态化”的趋势&#xff0c;无疑是一个巨大的技术红利。而数据规模爆发式增长的今天&#xff0c;移动和访问云端数据却成为困扰企业的一大难题。不过幸运的是&#xff0c;在对象…

ES6:promise简单学习

一、理解promise Promise将异步执行的程序变成同步执行&#xff0c;所谓的在开发中解决回调嵌套的问题 Promise 是异步编程的一种解决方案 从语法上讲&#xff0c;promise是一个对象 从它可以获取异步操作的消息 从本意上讲&#xff0c;它是承诺&#xff0c;承诺它过一段时间会…

Java入门超详细(内含Java基础 Java高级)

Java基础入门 - 内含Java基础&#xff0c;Java高级 Java 基本介绍Java 学习须知Java 学习文档Java 基础Java 基础语法Java 对象与类Java 基本数据类型Java 变量类型Java 修饰符Java 运算符Java 循环结构Java 条件语句Java switch caseJava 数组Java 日期与时间Java 正则表达式J…

Swift AsyncSequence — 代码实例详解

前言 AsyncSequence 是并发性框架和 SE-298 提案的一部分。它的名字意味着它是一个提供异步、顺序和迭代访问其元素的类型。换句话说&#xff1a;它是我们在 Swift 中熟悉的常规序列的一个异步变体。 就像你不会经常创建你的自定义序列一样&#xff0c;我不期望你经常创建一个…

2022 Jiangsu Collegiate Programming Contest A. PENTA KILL!

题目链接 Sample 1 Input 10 Bin Guigo Grevthar Bin GALA Grevthar GALA TitaN GALA Guigo GALA Aegis GALA Jojo GALA Grevthar Xiaohu Grevthar GALA Aegis Output PENTA KILL! Sample 3 Input 7 GALA Jojo Aegis Ming GALA Grevthar GALA Grevthar GALA Aegis GALA Guigo…

树莓派硬件介绍及配件选择

目录 树莓派Datasheet下载地址&#xff1a; Raspberry 4B 外观图&#xff1a; 技术规格书&#xff1a; 性能介绍&#xff1a; 树莓派配件选用 电源的选用&#xff1a; 树莓派外壳选用&#xff1a; 内存卡/U盘选用 树莓派Datasheet下载地址&#xff1a; Raspberry Pi …

CompletableFutrue异步处理

异步处理 一、线程的实现方式 1. 线程的实现方式 1.1 继承Thread class ThreadDemo01 extends Thread{Overridepublic void run() {System.out.println("当前线程:" Thread.currentThread().getName());} }1.2 实现Runnable接口 class ThreadDemo02 implements …

故障:更新后电脑卡顿

前一天下班的时候关电脑&#xff0c;关机选项变成了“更新并关机”&#xff0c;没多想&#xff0c;我点了。。。。早上上班就发现电脑卡得不行&#xff0c;看了下更新日志&#xff0c;装了一大堆东西&#xff0c;看了下任务管理器&#xff0c;内存直接跑到了90%&#xff0c;这电…

每日学术速递5.2

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.DataComp: In search of the next generation of multimodal datasets 标题&#xff1a;DataComp&#xff1a;寻找下一代多模态数据集 作者&#xff1a;Samir Yitzhak Gadre, Gab…

【JAVA模块六------ 综合案例基础巩固】

JAVA模块六------ 综合案例基础巩固 1 逢7跳过2 数组元素求和3 判断两个数组的内容是否相同4 查找某个数组元素索引5 数组元素反转输出&#xff1a;&#xff08;逆序输出&#xff09;6 评委打分7 随机产生验证码其他&#xff1a;方法抽取&#xff1a; 1 逢7跳过 要求&#xff1…

国产光伏仪器 6581太阳能电池板伏安特性测试仪

6581太阳能电池板伏安特性测试仪主要用于太阳能电池板生产的最终测试&#xff0c;也可以作为层压前测试使用&#xff0c;能大大提高一次封装成品率。该测试仪适合于单晶、多晶、薄膜等多种电池组件&#xff0c;可进行I-V曲线、P-V曲线、短路电流、开路电压、峰值功率等全部参数…

Hive SQL on Flink 构建流批一体引擎

摘要&#xff1a;本文整理自阿里巴巴开发工程师罗宇侠、阿里巴巴开发工程师方盛凯&#xff0c;在 Flink Forward Asia 2022 流批一体专场的分享。本篇内容主要分为五个部分&#xff1a; 1. 构建流批一体引擎的挑战 2. Hive SQL on Flink 3. 流批一体引擎的收益 4. Demo 5. 未来…

做到“有效沟通”,帮你达到这3个目的

在项目管理中&#xff0c;团队沟通是至关重要的。团队成员之间应该建立良好的沟通机制&#xff0c;及时沟通和协调问题&#xff0c;避免出现问题后甩锅的情况。 在实际项目中&#xff0c;很多问题出现的原因是团队沟通不畅&#xff0c;项目经理需要加强团队沟通的重要性&…

K8S二进制安装报错及各个组件功能介绍

目录 一、K8S安装二、安装时遇到的几个问题2.1、Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kuberne…

C语言复习笔记2

1.变量命名只能以数字、字母、下划线组成并且不能以数字开头。 #include<stdio.h> #include<unistd.h>//变量名只能由数字字母下划线组成&#xff0c;不能以数字开头 int main() {//int 2b;return 0; }2.内存中保存的是补码 0的补码取反得补码再求源码是-1。 源码…