【数据结构】顺序表(上)

news2024/11/15 11:30:05

所属专栏:初始数据结构
博主首页:初阳785
代码托管:chuyang785>
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!

【数据结构】顺序表(上)

  • 1.线性表
  • 1.1概念
  • 2.顺序表
    • 2.1顺序表的概念及结构
  • 3.使用顺序表实现接口
    • 3.1 seqList.h头文件展示
    • 3.2 seqList.c源文件展示
    • 3.3 test.c源文件展示
    • 3.4初始化结构体
    • 3.5检查容量
    • 3.6尾插
    • 3.7数据展示
    • 3.8尾删
    • 3.9头插
    • 3.10头删
  • 4.自主设计

1.线性表

1.1概念

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

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

顺序表的本质就是数组,但是不同于数组的时顺序表分动态的和静态的。
而且顺序表存放数据必须是连续的,数组没有要求。

在这里插入图片描述
看起来有点想数组。

2.顺序表

2.1顺序表的概念及结构

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

顺序表就是数组,但是在数组的基础上它还要求数据是从头开始连续存储的,不能跳跃间隔。

3.使用顺序表实现接口

所谓接口,就相当于已经设计好的程序,如果要用的话就是接调用这个接口。
你可以这样理解,我们在拧螺丝的时候可能需要不同的工具头,可能是平头的,也可能是交叉的,而我们如果想使用的话只需要把不同的工具头套在我们把手上使用即可,这些工具头就是我们的接口。

3.1 seqList.h头文件展示

#pragma once //防止头文件被重复包含
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size;// 表示数组中存储了多少个数据
	int capacity;//数组实际能存放数据的空间间容量是多大
}SL;

// 接口函数--命名风格是跟着STL走的
//初始化
void SeqListPrint(SL* ps);
//打印数据
void SeqListInit(SL* ps);
//销毁空间
void SeqListDestory(SL* ps);

//检查容量
void SeqListCheckCapacity(SL* ps);
//尾插
void SeqListPushBack(SL* ps, SLDataType x);
//尾删
void SeqListPopBack(SL* ps);
//头插
void SeqListPushFront(SL* ps, SLDataType x);
//头删
void SeqListPopFront(SL* ps);

3.2 seqList.c源文件展示

#include "seqList.h"

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

//初始化
void SeqListInit(SL* ps)
{
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

//空间回收
void SeqListDestory(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}

//检查容量
void SeqListCheckCapacity(SL* ps)
{
	//空间不足,扩容。
	//SeqListCheckCapacity(ps);
	if (ps->size == ps->capacity)//没空间或者空间满了
	{

		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		//ps->capacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		// 
		//if (ps->capacity == 0)
		//{
		//	ps->capacity = 4;
		//}
		//else
		//{
		//	ps->capacity = ps->capacity * 2;
		//}
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("relloc fial\n");
			exit(-1);//退出函数
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

//尾插
void SeqListPushBack(SL* ps, SLDataType x)
{
	SeqListCheckCapacity(ps);
	ps->a[ps->size] = x;
	//printf("%d ", ps->a[ps->size]);
	ps->size++;
} 

//尾删
void SeqListPopBack(SL* ps)
{
	//温柔的处理方式
	//if (ps->size > 0)
	//{
	//	ps->size--;
	//}

	//暴力的处理方式
	assert(ps->size > 0);
	ps->size--;
}
//头插
void SeqListPushFront(SL* ps, SLDataType x)
{
	//判断是否满了
	SeqListCheckCapacity(ps);

	int end = 0;
	for (end = ps->size - 1; end >= 0; end--)
	{
		ps->a[end+1] = ps->a[end];
	}
	ps->a[0] = x;
	ps->size++;
}
//头删
void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);

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

3.3 test.c源文件展示

本章节主要是实现接口函数的,我们的test.c源文件只是用来检测我们的接口函数是否正确,所以不做要求。

3.4初始化结构体

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;
	int size;// 表示数组中存储了多少个数据
	int capacity;//数组实际能存放数据的空间间容量是多大
}SL;

注意:这我们用了一个关键字typedef,typedef int SLDataType这里我我们将int进行重命名位
SLDataType,应为我们这是在实现接口,我们的接口要尽量的通用,这里我们要设计的数据类型可能不是int,肯能是double也可能是其他的类型的,所以如果我们要改的话只要在关键字那里改就行了,就会很方便。

3.5检查容量

void SeqListCheckCapacity(SL* ps)
{
	//空间不足,扩容。
	//SeqListCheckCapacity(ps);
	if (ps->size == ps->capacity)//没空间或者空间满了
	{

		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//这里先给4给大小的容量
		//ps->capacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		 上面的三目操作发等同以下
		//if (ps->capacity == 0)
		//{
		//	ps->capacity = 4;
		//}
		//else
		//{
		//	ps->capacity = ps->capacity * 2;
		//}
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("relloc fial\n");
			exit(-1);//退出函数
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}

这里我们使用到了realloc动态内存开辟函数,realloc函数有个特点就是内存不够的时候它可以继续开辟内存,而且当我们我们还没有开辟内存的时候,第一次开辟内存等同于malloc。

3.6尾插

void SeqListPushFront(SL* ps, SLDataType x)
{
	//判断是否满了
	SeqListCheckCapacity(ps);

	int end = 0;
	for (end = ps->size - 1; end >= 0; end--)
	{
		ps->a[end+1] = ps->a[end];
	}
	ps->a[0] = x;
	ps->size++;
}

这里最关键的是判断容量,如果满了我们就扩容。

3.7数据展示

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

这个就没什么好说的,一个for循环就解决了。

3.8尾删

void SeqListPopBack(SL* ps)
{
	//温柔的处理方式
	//if (ps->size > 0)
	//{
	//	ps->size--;
	//}

	//暴力的处理方式
	assert(ps->size > 0);
	ps->size--;
}

我们的查询数据的原理其实和数组是一样的,所以只要我们遍历不到我们想要的数据的下标就打印不出来,就等同于删除数据了。但是这里我们要注意的是如果我们的数据已经删完了,我们的ps->size就不能继续–下去了,不然就会得到负数,显然会出现错误。

3.9头插

void SeqListPushFront(SL* ps, SLDataType x)
{
	//判断是否满了
	SeqListCheckCapacity(ps);

	int end = 0;
	for (end = ps->size - 1; end >= 0; end--)
	{
		ps->a[end+1] = ps->a[end];
	}
	ps->a[0] = x;
	ps->size++;
}

在进行头插的时候我们想到的办法就是平移法:
在这里插入图片描述
就是我们把现有的数据整体的网后平移一个位置,同时size++(还有就是别忘记判断容量)然后再在得一个位置插入我们的数据就行了。

3.10头删

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);

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

在进行头删的时候我们想到的办法就是平移法:
在这里插入图片描述
就是把后后面的数据整体的向前推进一个位置,同时我们的size–;同样的也别忘记判断是否删完了。

4.自主设计

写到这里相信看到这的小伙伴们对我们的接口函数已经有基本的了解了,我们可以自己设计一些接口函数在这里我就给小伙伴们带来了三个个接口函数的设计:

  1. 给定一个下标要求查找数据,找到了返回下标否则返回-1。
  2. 给定一个下标要求在这个下标插入数据。
  3. 给定一个下标要求在这个下标删除数据。
    函数定义:
//找到x并返回它的下标,找不到返回-1
int SeqListFind(SL* ps, SLDataType x);
//给定一个位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x);
//给定一个位置删除
void SeeqListErase(SL* ps, int pos);

小伙伴们动起手来吧!!!!!!
我们会在下一节进行详细的讲解。

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

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

相关文章

(十六)排序算法-桶排序

1 基本介绍 1.1 概述 桶排序 &#xff08;Bucket sort&#xff09;或所谓的箱排序&#xff0c;是一个排序算法&#xff0c;工作的原理是将数组分到有限数量的桶里。每个桶再个别排序&#xff08;有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序&#xff09;&a…

ZYNQ:【1】深入理解PS端的TTC定时器(Part1:原理+官方案例讲解)

碎碎念&#xff1a;好久不见&#xff0c;甚是想念&#xff01;本期带来的是有关ZYNQ7020的内容&#xff0c;我们知道ZYNQ作为一款具有硬核的SOC&#xff0c;PS端很强大&#xff0c;可以更加便捷地实现一些算法验证。本文具体讲解一下里面的TTC定时器&#xff0c;之后发布的Part…

Java-初识 .class 文件

一、概述 class文件全名称为 Java class 文件&#xff0c;主要在平台无关性和网络移动性方面使 Java 更适合网络。该文件打破了 C 或者 C 等语言所遵循的传统&#xff0c;使用这些传统语言写的程序通常首先被编译&#xff0c;然后被连接成单独的、专门支持特定硬件平台和操作系…

面试被问到vue的diff算法原理,我不允许你回答不上来

一、是什么 diff 算法是一种通过同层的树节点进行比较的高效算法 其有两个特点&#xff1a; 比较只会在同层级进行, 不会跨层级比较在diff比较的过程中&#xff0c;循环从两边向中间比较 diff 算法在很多场景下都有应用&#xff0c;在 vue 中&#xff0c;作用于虚拟 dom 渲…

nvm实现多版本node自由切换

nvm&#xff0c;全称是node.js version management,可以在多个node版本之间自由切换&#xff01; 1、下载文件 github Releases coreybutler/nvm-windows GitHub 2、安装nvm 注意&#xff1a;安装前必须完全卸载node 彻底从Windows中删除Node.js 1、从卸载程序卸载程序和功…

【性能测试】Jemeter+mysql+CSV+InfluxDB+Granafa数据库性能测试及监控

Jmeter连接Mysql并执行事务 一、下载驱动并加入jmeter 1.mysql驱动下载地址&#xff1a;MySQL :: Download MySQL Connector/J (Archived Versions) 找到对应的驱动下载(版本一定要对应) 2.下载后&#xff0c;解压&#xff0c;找到驱动jar包复制到桌面&#xff1a; 3.把驱动j…

CODOSYS之结构化文本(ST)——中级篇(一)计时器的应用

标准库中常用的计时器有如下四个&#xff08;部分环境还支持高精度计时器如LTON等等&#xff09;&#xff1a; .RTC .TON .TOF .TP 本文将对将对上述四个计时器进行简单的讲解。 .RTC&#xff1a; RunTime 时钟定时器&#xff0c;返回启动时间&#xff0c;当前时间和日…

别搞了 软件测试真卷不动了...

内卷可以说是 2022年最火的一个词了。2023 年刚开始&#xff0c;在很多网站看到很多 软件测试的 2022 年度总结都是&#xff1a;软件测试 越来越卷了&#xff08;手动狗头&#xff09;&#xff0c;2022 年是被卷的一年。前有几百万毕业生虎视眈眈&#xff0c;后有在职人员带头“…

L2-042 老板的作息表(极短代码)

题目&#xff1a; 新浪微博上有人发了某老板的作息时间表&#xff0c;表示其每天 4:30 就起床了。但立刻有眼尖的网友问&#xff1a;这时间表不完整啊&#xff0c;早上九点到下午一点干啥了&#xff1f; 本题就请你编写程序&#xff0c;检查任意一张时间表&#xff0c;找出其中…

企业推广常用的网络推广方法有哪些?

网络推广是指通过互联网向目标用户推广产品、服务或品牌的过程&#xff0c;其主要目的是为了扩大业务范围&#xff0c;提高企业知名度&#xff0c;增加销售额。在当今的数字化时代&#xff0c;网络推广已经成为了企业不可或缺的一部分。本文将介绍一些常见的网络推广方法和途径…

Linux安装中文字体

前言 Lunix默认没有中文字库&#xff0c;很容易导致项目开发时出现中文字符乱码的情况。 1 查看linux已安装字体 fc-list如出现-bash: fc-list: command not found 说明Linux中没有安装字体库&#xff0c;需要先安装字体库 2 Linux安装字体 yum -y install fontconfig执行…

不平衡电网电压下虚拟同步发电机VSG控制策略-实现不平衡电压下控制三相电流平衡

资源地址&#xff1a; 不平衡电网电压下虚拟同步发电机VSG控制策略-实现不平衡电压下控制三相电流平衡-电子商务文档类资源-CSDN文库 主体模型&#xff1a; VSG控制&#xff1b;正负序分离&#xff1b;正负序控制&#xff1b;电压电流双环控制&#xff01;&#xff01;&…

[LCA]最近公共祖先(倍增)

概念引入 祖先 祖先其实很好理解&#xff0c;一个节点的 **父节点 以及 父节点的父节点 以及 父节点的父节点的父……**都是这个节点的祖先 比如说上面的 ddd 节点&#xff0c; bbb 节点和 aaa 节点都是它的祖先 kkk 级祖先 称节点 &#x1d465; 的父节点为 &#x1d465; …

带你走进Flutter 3.7

期待已久的新教程上线啦&#xff01;解锁Flutter开发新姿势&#xff0c;一网打尽Flutter最新与最热技术&#xff0c;点我Get!!! 新年伊始&#xff0c;由 Flutter 3.7 正式版来「打头阵」&#xff01;我们与整个 Flutter 社区们继续在 Flutter 3.7 中优化了框架&#xff0c;包括…

(一)Linux:自由、开放、灵活的操作系统内核

目录 一、Linux的发展史 二、linux的开源 三、目前的现状 四、企业应用现状 五、发行的版本 六、安装与使用 七、利用云服务器配置Linux环境 一、Linux的发展史 Linux是一款由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;开发的操作系统内核&#xff0c;它的发布…

用 logging 模块将信息输出到日志文件

当你要用到一些信息去统计画图&#xff0c; 或者你的输出太长了&#xff0c;出现了那种“折叠”&#xff0c;就是说“内容超过1000行”&#xff0c;结果等下一次进入环境&#xff0c;你只能看到结尾的输出&#xff0c;却看不到开头的输出了&#xff0c; 那么你可以使用 Pytho…

【NLP实战】基于Bert和双向LSTM的情感分类【上篇】

文章目录前言简介数据获取与提取数据清洗读取数据&#xff0c;查看数据清洗训练集观察数据分布去除空数据去除重复数据关于去除停用词关于特殊符号储存清洗后的数据集清洗测试集观察数据分布去除空数据去除重复数据(并储存)清洗验证集观察数据分布去除空行去除重复数据(并储存)…

Go分布式爬虫(二十四)

文章目录24 存储引擎爬取结构化数据step1 从首页获取热门标签信息step2 获取图书列表step3 获取图书详情完整规则存储到MySQL数据抽象数据存储存储引擎实现存储引擎验证dockerdocker-compose使用Navicat查看使用DataGrip查看24 存储引擎 爬虫项目的一个重要的环节就是把最终的…

Mysql逻辑架构和语句执行流程

文章目录1. 逻辑架构剖析1.1 连接管理--连接层1.2 解析与优化--服务层1.3 存储引擎2. SQL语句的执行流程2.1 执行原理2.2 语法顺序1. 逻辑架构剖析 当一个客户端连接mysql服务器执行一条查询语句时&#xff0c;会发生以下处理过程&#xff1a; 1.1 连接管理–连接层 客户端想…

1.半导体基础知识

1.半导体基础知识本征半导体什么是半导体&#xff1f;什么是本征半导体&#xff1f;本征半导体的结构本征半导体中的两种载流子为什么将自然界导电性能中等的半导体材料制成本征半导体杂质半导体N型半导体P型半导体PN结PN结中的扩散运动漂移运动和PN结的形成PN结的单向导电性PN…