[数据结构 - C语言] 顺序表

news2024/9/21 11:16:10

目录

1、线性表

2、顺序表

2.1 顺序表的概念

2.2 接口

3、接口实现

3.1 初始化

3.2 销毁

3.3 容量检测

3.4 打印数据

3.5 顺序表的头插

3.6 顺序表的尾插

3.7 顺序表的头删、尾删

3.8 顺序表查找

3.9 指定位置插入数据


1、线性表

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


2、顺序表

2.1 顺序表的概念

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

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

#define N 10

struct SeqList
{
	int a[N];
	int size;
};

静态顺序表缺点:开的大了浪费空间,小了不够用。

优点:可以通过下标访问任意一个数组元素。

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

动态的顺序表比起静态的顺序表就很灵活了,空间不够用可以随时增容。

2.2 接口

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、接口实现

3.1 初始化

void SeqListInit(SeqList* ps)
{
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}

	ps->size = 0;
	ps->capacity = 4;
}

使用malloc在堆区开辟动态内存,开4个整形的空间。容量也就初始化为4。

3.2 销毁

void SeqListDestroy(SeqList* ps)
{
	assert(ps);
	free(ps);
	ps->a = NULL;
	
	ps->capacity = 0;
	ps->size = 0;
}

在销毁的时候我们使用 free ,来将开辟的整个顺序表的内存释放掉,并将头指针置为空。

3.3 容量检测

void SeqCheckCapacity(SeqList* ps)
{
	if (ps->capacity == ps->size)
	{
		SLDateType* tmp = (SLDateType*)realloc(sizeof(SLDateType), 2 * ps->capacity);
		ps->a = tmp;
		if (ps->a == NULL)
		{
			perror("realloc fail:");
			return;
		}
		ps->capacity *= 2;
	}
}

如果 4 个整型空间被使用完了就得继续开辟空间,因此我们使用 realloc 再开辟空间,合理的是再开辟的空间大小为原来的二倍。

3.4 打印数据

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

对数组遍历,打印每个元素。

3.5 顺序表的头插

void SeqListPushFront(SeqList* ps, SLDateType x)
{
	assert(ps);
	SeqCheckCapacity(ps);
	int begin = 0;
	for (begin = ps->size; begin > 0; begin--)
	{
		ps->a[begin] = ps->a[begin - 1];
	}
	ps->a[0] = x;
	ps->size++;
}

插入前我们调用容量检测函数对容量进行检测,函数内部已经写好了增容的程序。

分析:

在头插的时候我们要将数组从后往前移动。

3.6 顺序表的尾插

void SeqListPushBack(SeqList* ps, SLDateType x)
{
	assert(ps);
	SeqCheckCapacity(ps);

	ps->a[ps->size] = x;
	ps->size++;
}

顺序表的尾插还是先要检测容量是否足够。

分析:

3.7 顺序表的头删、尾删

//头删
void SeqListPopFront(SeqList* ps)
{
	assert(ps);

	int begin = 0;
	for (begin = 0; begin < ps->size - 1; begin++)
	{
		ps->a[begin] = ps->a[begin + 1];
	}
	ps->size--;
}
//尾删
void SeqListPopBack(SeqList* ps)
{
	assert(ps);

	ps->a[ps->size - 1] = 0;
	ps->size--;
}

分析:

头删

尾删

将 size-1 位置上的数字置 0,让 size-- 就完成尾删操作。

3.8 顺序表查找

约定:找到返回下标,没找到返回 -1。

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

遍历数组就可以完成操作。

3.9 指定位置插入数据

void SeqListInsert(SeqList* ps, int pos, SLDateType x)
{
    assert(pos>=0 && pos <= ps->size);
    
	int end = 0;
	for (end = ps->size - 1; end >= pos; end--)
	{
		ps->a[end + 1] = ps->a[end];
	}
	ps->a[pos] = x;
	ps->size++;
}

注意:

1.pos 位置要合法,0<= pos <= size;

2.依旧是从后往前覆盖;

3.如果pos = size 就是尾插,pos = 0 就是头插。

3.10 指定位置删除

void SeqListErase(SeqList* ps, int pos)
{
	assert(pos >= 0 && pos < ps->size);

	int begin = 0;
	for (begin = pos; begin < ps->size-1; begin++)
	{
		ps->a[begin] = ps->a[begin + 1];
	}

	ps->size--;
}

注意:

1.pos 位置要合法,0<= pos <= size-1;

2.从 pos 位置开始,到 size-1 位置结束,将 begin+1 的元素移到 begin 位置;

3.如果pos = size-1 就是尾删,pos = 0 就是头删。

完整代码在代码仓库,入口--->C语言: C语言的初级阶段时期 - Gitee.com

********************************************本片结束**********************************************

大牛的你看到有什么问题请一定要指出来。如果看了有收获,点赞收藏+关注三连一波。

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

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

相关文章

认识HTTPS以及了解HTTPS的加密过程

目录 简单认识HTTPS&#xff1a; 运营商劫持&#xff1a; 加密的理解&#xff1a; HTTPS的工作过程&#xff1a; 对称加密&#xff1a; 非对称加密&#xff1a; 中间人攻击 证书 简单认识HTTPS&#xff1a; HTTPS 也是一个应用层协议。是在 HTTP 协议的基础上引…

逆向-还原代码之(*point)[4]和char *point[4] (Interl 32)

// source code #include <stdio.h> #include <string.h> #include <stdlib.h> /* * char (*point)[4] // 数组指针。 a[3][4] // 先申明二维数组,用它来指向这个二维数组 * char *point[4] // 指针数组。 a[4][5] // 一连串的指针…

客快物流大数据项目(一百一十六):远程调用 Spring Cloud Feign

文章目录 远程调用 Spring Cloud Feign 一、​​​​​​​简介

OpenGL入门之 深入三角形

一、引言 本教程使用GLEW和GLFW库。  通过本教程&#xff0c;你能轻松的、深入的理解OpenGL如何绘制一个三角形。  如果你不了解OpenGL是什么&#xff0c;可以阅读OpenGL深入理解。 二、基本函数和语句介绍 通过阅读以下的函数&#xff0c;你的大脑里能留下关于OpenGL基本函…

【每日一题Day184】LC1187使数组严格递增 | dp

使数组严格递增【LC1187】 给你两个整数数组 arr1 和 arr2&#xff0c;返回使 arr1 严格递增所需要的最小「操作」数&#xff08;可能为 0&#xff09;。 每一步「操作」中&#xff0c;你可以分别从 arr1 和 arr2 中各选出一个索引&#xff0c;分别为 i 和 j&#xff0c;0 <…

前端学习:HTML块、类、Id

目录 快 一、块元素、内联元素 二、HTML 元素 三、HTML元素 类 一、分类块级元素 二、分类行内元素 Id 一、使用 id 属性 二、 class与ID的差异 三、总结 快 一、块元素、内联元素 大多数HTML元素被定义为块级元素或内联元素。 块级元素在浏览器显示时&#xff0c;通常会…

Docker常用命令详解,有这些足够了

首先启动类 启动docker&#xff1a;systemctl start docker 停止docker&#xff1a;systemctl stop docker 重启docker&#xff1a;systemctl restart docker 查看docker状态&#xff1a;systemctl status docker 开机自启动&#xff1a;systemctl enable docker 查看docker概要…

【CocosCreator入门】CocosCreator组件 | Widget(对齐)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中的Widget组件用于UI布局和调整&#xff0c;可以通过调整Widget组件来实现UI元素的自适应和排版。 目录 一、组件介绍 二、组件属性 三、组件使用 四、脚本示例 一、组件介绍 在Coc…

Python中的统计学(二)

大数定律和中心极限定律都是概率论中重要的定理。它们之间的不同在于它们所涉及的随机变量和极限的不同。 大数定律是指随着样本容量的增大&#xff0c;样本均值越来越接近于总体均值的定律。即样本均值的极限等于总体均值&#xff0c;也就是说&#xff0c;当样本量足够大时&a…

绝了!!PDF转换没想到这么简单

PDF处理是很多小伙伴的“痛”&#xff0c;在工作学习中&#xff0c;PDF转换、PDF编辑、PDF和图片的各种问题都是需要快速解决的&#xff0c;但市面上不少付费的软件让我们很是肉痛&#xff01; 今天给大家推荐5个免费的神仙PDF转换网站&#xff0c;解决你的所以PDF问题~ 记得…

Simulink 自动代码生成电机控制:硬件开发板系统介绍

目录 前言 电源电路 MCU电路 开发板接口 关于电流采样和过流保护 驱动部分 总结 前言 在介绍开发板之前突然有感而发想多说两句&#xff0c;本人从事电控行业也是有一些年头了&#xff0c;除了刚刚毕业就接触的电机控制外&#xff0c;就是电源控制相关的&#xff0c;像三相P…

Point-to Analysis指针分析(2)

https://blog.csdn.net/qq_43391414/article/details/111046505 下面介绍一种新的指针分析的算法Steensgaard算法&#xff0c;并将其与上一篇文章介绍 Steensgaard算法 不同于Andersen算法,Steensgaard在前者的基础上&#xff0c;再次对问题进行了简化&#xff0c;从而指针分析…

远程访问及控制

目录 一、SSH远程管理 1&#xff09;SSH的简介 2&#xff09;SSH的优点 3&#xff09;常用的SSH软件的介绍 4&#xff09;SSH 的组成 5&#xff09;SSH的密钥登录 密钥登录的过程&#xff1a; 二、SSH的运用 1 &#xff09;SSH配置文件信息 2&#xff09;存放ssh服务…

JAVA 进程CPU过高排查

1. top命令看一下JAVA进程&#xff1a; 占用500%多&#xff0c;非常恐怖&#xff0c;程序卡得动不了了。 2. 使用命令top -H -p PID 此处PID就是上一步获取的进程PID&#xff0c;我的PID是13342&#xff0c;通过此命令可以查看实际占用CPU最高的的线程的ID&#xff0c;此处几位…

ChatGPT+Ai绘图【stable-diffusion实战】

ai绘图 stable-diffusion生成【还有很大的提升空间】 提示词1 Picture a planet where every living thing is made of light. The landscapes are breathtakingly beautiful, with mountains and waterfalls made of swirling patterns of color. What kind of societies m…

【学习笔记】unity脚本学习(五)【常用的方法函数Destroy、Instantiate 、SendMessage、invoke 、Coroutine】

目录 常用的方法函数Object体系结构MonoBehaviour复习继承的变量 继承自Object的方法Destroy 物体的销毁DestroyImmediate 立即销毁对象&#xff08;强烈建议您改用 Destroy&#xff09;Object.DontDestroyOnLoadObject.Instantiate 物体的生成类子弹生成案例 继承自Component的…

八股+面经

文章目录 项目介绍1.不动产项目数据机器学习算法调研图像提取算法调研数据集-ImageNetXceptionVGGInceptionDensenetMobilenet 2.图书项目技术栈面试问题 Java基础MapHashMap v.s Hashtable(5点)ConcurrentHashMap v.s Hashtable(2点)代理模式1. 静态代理2. 动态代理2.1 JDK 动…

什么样的人适合学习网络安全?怎么学?

有很多想要转行网络安全或者选择网络安全专业的人在进行决定之前一定会有的问题&#xff1a;什么样的人适合学习网络安全&#xff1f;我适不适合学习网络安全&#xff1f; 会产生这样的疑惑并不奇怪&#xff0c;毕竟网络安全这个专业在2017年才调整为国家一级学科&#xff0c;…

elasticsearch——数据同步

目录 数据同步思路分析 方案一&#xff1a;同步调用 方案二&#xff1a;异步通知 方案三&#xff1a;监听binlog 区别 关于elasticsearch与数据库数据同步 导入课前资料提供的hotel-admin项目&#xff0c;启动并测试酒店数据的CRUD 声明exchange、queue、RoutingKey 导…

Python列表和字典前面为什么会加星号(**)?

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 python 中&#xff0c;单星号*和双星号**除了作为“乘”和“幂”的数值运算符外&#xff0c; 还在列表、元组、字典的操作中有着重要作用。 一、列表&#xff08;list&#xff09;、元组&#xff08;tuple&#xff09…