数据结构与算法(C语言版)P2---线性表之顺序表
前景回顾
1、线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但在物理结构上并不一定是连续的,线性表在物理上存储时,通常以__数组__和__链式结构__的形式存储。
顺序表本质上就是数组。

2、顺序表
2.1、概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删改查。
顺序表就是数组,但是在数组的基础上,它还要求数据是从头开始存储并且是连续存储的,不能跳跃间隔。
顺序表一般可以分为:
1、静态顺序表:使用固定长数组存储元素。

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

3、顺序表的实现
【说明】:这里使用动态数组来实现顺序表。
顺序表主要有以下几个接口功能:
- 打印(SeqListPrint)
- 结构体初始化(SeqListInit)
- 释放空间(SeqListDestory)
- 检查扩容(SeqListCheckCapacity)
- 头插(SeqListPushBack)
- 头删(SeqListPopBack)
- 尾插(SeqListPushFront)
- 尾删(SeqListPopFront)
- 查找元素(SeqListFind)
- 在指定pos下标位置插入元素(SeqListInsert)
- 删除pos位置的数据(SeqListErase)
3.1、定义结构体
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDataType;typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SL;
a指针变量表示需要动态开辟的数组。
size变量表示数组中有效数据个数。
capacity变量表示动态开辟数组的空间大小。
3.2、结构体初始化接口实现
//结构体初始化
void SeqListInit(SL* ps)
{ps->a = NULL;ps->size = ps->capacity = 0;
}
3.3、检查扩容接口实现
因为我们采用动态开辟数组的形式来实现顺序表,所以当我们在进行任何一个插入操作时,都需要先申请空间,以便数据的插入。
这里有几种情况需要我们处理:
- 整个顺序表没有空间,扩容
- 空间不够,扩容。
- 空间足够,直接插入数即可。
void SeqListCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newcapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newcapacity;}
}
3.4、头插接口实现
void SeqListPushFront(SL* ps, SLDataType x)
{SeqListCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}
头插的核心思想:将全体数据元素向后移动。比如现在有数组int b = [1,2,3,4,5],现在想头插数据6,可以采取这样的方法:把1,2,3,4,5全部整体向后移一位。然后再把6进行头插。
3.5、打印接口实现
void SeqListPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}
3.6、销毁接口实现
void SeqListDestroy(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}
3.7、头删接口实现
void SeqListPopFront(SL* ps)
{//这里需要加个判断,判断size是否>0,否则防止越界访问if (ps->size > 0){int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;}
}
头删核心思想:把数组中下标为1到下标为最后一个的所有元素全部向前移动。
3.8、尾插接口实现
void SeqListPushBack(SL* ps, SLDataType x)
{//先检查扩容SeqListCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}
3.9、尾删接口实现
void SeqListPopBack(SL* ps)
{if (ps->size > 0){ps->size--;}
}
3.10、查询指定元素
//查询指定元素,并返回下标
int SeqListFind(SL* ps, SLDataType x)
{for (int i = 0; i < ps->size; i++){if (x == ps->a[i]){return i;}}return -1;
}
3.11、在指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(pos >= 0 && ps->size >= pos);SeqListCheckCapacity(ps);int end = ps->size - 1;while (pos <= end){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}
3.12、删除pos下标位置的数据
void SeqListErase(SL* ps, int pos)
{assert(pos >= 0 && ps->size > pos);int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}
以上就是使用动态数组实现顺序表的过程。下面展示全代码。
4、全代码展示
这里使用三个文件:
- seqlist.h:用于结构体、各种函数接口的声明。
- seqlist.c:用于各种函数接口的定义。
- test.c:用于创建顺序表,实现顺序表。
4.1、seqlist.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLDataType;typedef struct SeqList
{SLDataType* a;int size;int capacity;
}SL;//结构体初始化
void SeqListInit(SL* ps);//检查扩容
void SeqListCheckCapacity(SL* ps);//头插
void SeqListPushFront(SL* ps, SLDataType x);//打印
void SeqListPrint(SL* ps);//销毁
void SeqListDestroy(SL* ps);//头删
void SeqListPopFront(SL* ps);//尾插
void SeqListPushBack(SL* ps, SLDataType x);//尾删
void SeqListPopBack(SL* ps);//查询指向元素,并返回下标
int SeqListFind(SL* ps, SLDataType x);//在指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x);//删除pos下标位置的数据
void SeqListErase(SL* ps, int pos);
4.2、seqlist.c
#include "list.h"//结构体初始化
void SeqListInit(SL* ps)
{ps->a = NULL;ps->size = ps->capacity = 0;
}//检查扩容
void SeqListCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = (SLDataType*)realloc(ps->a, sizeof(SLDataType) * newcapacity);if (tmp == NULL){printf("realloc fail\n");exit(-1);}ps->a = tmp;ps->capacity = newcapacity;}
}//头插
void SeqListPushFront(SL* ps, SLDataType x)
{SeqListCheckCapacity(ps);int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps->size++;
}//打印
void SeqListPrint(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}//销毁
void SeqListDestroy(SL* ps)
{free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;
}//头删
void SeqListPopFront(SL* ps)
{//这里需要加个判断,判断size是否>0,否则防止越界访问if (ps->size > 0){int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;}
}//尾插
void SeqListPushBack(SL* ps, SLDataType x)
{//先检查扩容SeqListCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;
}//尾删
void SeqListPopBack(SL* ps)
{if (ps->size > 0){ps->size--;}
}//扩展接口
//查询指定元素,并返回下标
int SeqListFind(SL* ps, SLDataType x)
{for (int i = 0; i < ps->size; i++){if (x == ps->a[i]){return i;}}return -1;
}//在指定pos下标位置插入
void SeqListInsert(SL* ps, int pos, SLDataType x)
{assert(pos >= 0 && ps->size >= pos);SeqListCheckCapacity(ps);int end = ps->size - 1;while (pos <= end){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}//删除pos下标位置的数据
void SeqListErase(SL* ps, int pos)
{assert(pos >= 0 && ps->size > pos);int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}
4.3、test.c
#include "list.h"int main()
{SL sl;SeqListInit(&sl);SeqListPushFront(&sl, 1);SeqListPushFront(&sl, 2);SeqListPushFront(&sl, 3);int pos = SeqListFind(&sl, 2);SeqListErase(&sl, pos);SeqListPrint(&sl);SeqListDestroy(&sl);return 0;
}
5、顺序表的优缺点
顺序表的缺陷:
- 空间不够了需要扩容,扩容是需要付出代价的。
- 避免频繁的扩容,我们满了基本都是扩2倍。这可能就会导致一定空间的浪费。
- 顺序表要求数据从开始位置连续存储,那么我们在头部或者中间位置插入、删除数据就需要挪动数据,有性能消耗,效率不高。
顺序表的优点:
- 支持随机访问。
- 存储密度大
相关文章:
数据结构与算法(C语言版)P2---线性表之顺序表
前景回顾 #mermaid-svg-sXTObkmwPR34tOT4 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sXTObkmwPR34tOT4 .error-icon{fill:#552222;}#mermaid-svg-sXTObkmwPR34tOT4 .error-text{fill:#552222;stroke:#552222;}#…...
AI写文章软件-怎么选择不同的AI写文章软件
在如今信息爆炸的时代,无论是学生、职场人士,还是创作者和企业家,写文章都是一项常见而又重要的任务。然而,随着科技的不断进步,AI写文章的软件也逐渐走进了人们的视野。 147GPT批量文章生成工具www.147seo.com/post…...
VSCode远程连接服务器报错:Could not establish connection to
参考:https://blog.csdn.net/weixin_42538848/article/details/118113262 https://www.jb51.net/article/219138.htm 刚开始把ssh文件夹中的known_hosts给删除了,发现没啥用。 之后在扩展Remote-SSH里面,把config file路径设置为ssh文件夹里…...
openssl 用法整理 —— 筑梦之路
用法一 生成自签名数字证书 # 生成私钥 openssl genpkey -algorithm RSA -out private.key# 生成证书请求 openssl req -new -key private.key -out certificate.csr# 使用私钥签署证书 openssl x509 -req -days 365 -in certificate.csr -signkey private.key -out certifica…...
Mac安装SPSS 26(含安装包)
Mac安装SPSS 26(含安装包) 安装包地址(百度网盘):https://pan.baidu.com/s/127ZJNRIMZaeR2hDilQT0Zg提取码: m5xj 查看是否允许安装任何来源的app 如果没有任何来源这个选项 打开终端输入:sudo spctl --master-disable回车之后输入password(注:电脑的…...
uniapp存值和取值方法
在UniApp中,可以使用全局变量、本地缓存和Vuex状态管理等方式来进行存值和取值。 全局变量:可以在App.vue文件的data中定义一个全局变量,在其他页面或组件中通过uni.$emit方法修改其值,并通过uni.$on方法监听值的变化。 // App.…...
Apache Beam 2.50.0发布,该版本包括改进功能和新功能
导读我们很高兴向您介绍 Beam 的新版本 2.50.0。该版本包括改进功能和新功能。请查看此版本的下载页面。 亮点 Spark 3.2.2 被用作 Spark 运行程序的默认版本(#23804)。Go SDK 新增默认本地运行程序,名为 Prism(#24789࿰…...
华为云云耀云服务器 L 实例评测|配置教程 + 用 Python 简单绘图
文章目录 Part.I IntroductionChap.I 云耀云服务器 L 实例简介Chap.II 参与活动步骤 Part.II 配置Chap.I 初步配置Chap.II 配置安全组 Part.III 简单使用Chap.I VScode 远程连接华为云Chap.II 简单绘图 Reference Part.I Introduction 本篇博文是为了参与华为“【有奖征文】华…...
栈的简单应用(利用Stack进行四则混合运算)(JAVA)
目录 中缀表达式转后缀表达式 图解 代码实现过程: 完整代码: 利用后缀表达式求值: 完整代码: 首先我们得先了解逆波兰表达式。 中缀表达式转后缀表达式 所谓的中缀表达式其实就是我们平时写的例如:࿱…...
Python---异常
捕获全部异常 语法: try: 可能发生的错误代码 except: 如果出现异常执行的代码 例子: try:open("test2.txt", "r", encoding"UTF-8") except:print("出现异常,文件不存在,换个模式打…...
视频编解码器H.264和H265有什么区别?
对于大型视频文件来说,视频编解码器至关重要,它可以将文件压缩为较小的尺寸,从而可以更轻松地存储和加快传输速度。而两种最常用的编解码器是H.264和H.265,那么它们两者之间有什么区别,哪一个更好呢? 1. 什…...
网络安全进阶学习第十六课——业务逻辑漏洞介绍
文章目录 一、什么是业务逻辑二、业务逻辑漏洞的成因三、逻辑漏洞的重要性四、业务逻辑漏洞分类五、业务逻辑漏洞——业务授权安全1、未授权访问2、越权访问1) 平行越权(水平越权是指相同权限的不同用户可以互相访问)2) 垂直越权(垂直越权是指…...
华为OD:跳房子I
题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏。 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格 跳房子的过程中,可以向前跳,也可以向后跳。 假设房子的总格数是count,小红每回合可能连续跳的…...
C语言自定义类型详解(1)结构体知识汇总
本篇概要 本篇主要讲述C语言结构体的相关知识,包括结构体的基本声明,结构体的匿名结构,结构体的自引用,结构体变量的定义和初始化以及结构体的内存对齐等相关知识。 文章目录 本篇概要1.结构体1.1结构体的基本声明1.2结构体的特殊…...
小程序中如何查看会员的访问记录
在小程序中,我们可以通过如下方式来查看会员的访问记录。下面是具体的操作流程: 1. 找到指定的会员卡。在管理员后台->会员管理处,找到需要查看访客记录的会员卡。也支持对会员卡按卡号、手机号和等级进行搜索。 2. 查看会员卡详情。点…...
SpringCloud Alibaba - Sentinel
接上文SpringCloud Alibaba - Nacos 1.Sentinel 流量防卫兵 1.1 安装与部署 和Nacos一样,它是独立安装和部署的,下载地址https://github.com/alibaba/Sentinel/releases 下载后的jar放到目录 然后配置 启动并访问,用户名密码都是 sentinel 此时就…...
内存泄漏,内存溢出,抽象类和接口,netstat、ping、ifconfig的区别
持续学习是我们必备的技能之一,保持与时俱进,保持行业的敏感度,关注行业发展趋势,了解新技术,加强自己的认知,积极的应对变化 内存泄漏 memory leak 是指程序在申请内存后,无法释放已申请的内…...
TensorFlow安装 ,在原本的虚拟环境下配置Tensorflow.
1.TensorFlow安装 ,在原本的虚拟环境下配置Tensorflowh和pytorch 2.我首先在anaconda的环境下创建了一个tensorflow文件夹 如何先进入D盘,再进入tensorflow文件夹的目录D:cd D:\Anaconda\TensorFlowSoftWarepip install tensorflow如图所示报错解决方法 …...
如何使用HTML, CSS和JavaScript开发一个浏览器打字游戏:从零到一的详细步骤与完整代码教程
第一部分:游戏概述与HTML结构 1. 游戏概述 打字游戏是一个训练用户打字速度和准确性的游戏。用户将会看到一个随机的单词或句子,并在限定时间内尽快准确地键入该单词或句子。每次正确输入,玩家得分,每次输入错误,扣分。这个游戏不仅能够增加用户的打字速度,还可以为学习…...
安卓玩机搞机----不用刷第三方官改固件即可享受“高级设置”的操作 ChiMi安装使用步骤
很多玩友特别喜欢第三方作者修改的带有高级设置的官改包。因为他可以随意修改系统里面的有关设置选项。包括但不限于修改状态栏 显示日期 秒等等的操作。 第三方带高级设置的官改 一般官改带高级设置的类似与 今天给大家分享下不用刷这些官改包即可享受高级设置的操作。 红米…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
