数据结构与算法(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安装使用步骤
很多玩友特别喜欢第三方作者修改的带有高级设置的官改包。因为他可以随意修改系统里面的有关设置选项。包括但不限于修改状态栏 显示日期 秒等等的操作。 第三方带高级设置的官改 一般官改带高级设置的类似与 今天给大家分享下不用刷这些官改包即可享受高级设置的操作。 红米…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
【多线程初阶】单例模式 指令重排序问题
文章目录 1.单例模式1)饿汉模式2)懒汉模式①.单线程版本②.多线程版本 2.分析单例模式里的线程安全问题1)饿汉模式2)懒汉模式懒汉模式是如何出现线程安全问题的 3.解决问题进一步优化加锁导致的执行效率优化预防内存可见性问题 4.解决指令重排序问题 1.单例模式 单例模式确保某…...
Electron简介(附电子书学习资料)
一、什么是Electron? Electron 是一个由 GitHub 开发的 开源框架,允许开发者使用 Web技术(HTML、CSS、JavaScript) 构建跨平台的桌面应用程序(Windows、macOS、Linux)。它将 Chromium浏览器内核 和 Node.j…...
