数据结构:顺序表

顺序表

  • 顺序表的概念与结构
    • 静态顺序表
    • 动态顺序表
  • 动态顺序表的实现
    • SeqList.h的创建
    • 初始化动态顺序表(LS_Init)
    • 动态顺序表的销毁(LS_Destry)
    • 检查动态内存空间是否已满(SL_CheckCapacity)
    • 动态顺序表打印有效数据(SL_Print)
    • 在末尾存放数据(SL_PushBack)
    • 在起始位置添加有效数据(SL_PushFront)
    • 在指定位置添加数据(SL_Inser)
    • 删除最后一位数据(SL_PopBack)
    • 在起始位置删除数据(SL_PopFront)
    • 删除任意位置的数据(SL_Deser)
    • 寻找内存中的某个数据的位置(Find)
  • 测试顺序表(test.c)

顺序表的概念与结构

概念:顺序表就是在内存中申请一段连续的空间来存放我们需要存放的数据,一般使用数组的方法来实现。
那顺序表跟数组有什么区别?
他们的本质是一样的,都是使用数组来存放数据。
顺序表相当于数组的加工与包装。
就好比我们下馆子吃的清炒西兰花,在米其林餐厅就会通过摆盘与封装,改个名字叫绿野仙踪,使其看起来更加高大上。
但是我们不能说顺序表就是数组,他们是不等价的,只能说底层结构采用的是数组的方式来实现我们的目的。

静态顺序表

我们学习C语言,肯定知道静态内存或者动态内存。
那静态顺序表也一样,就是利用定长数组来存放数据,它的空间在确定之后是不能随便更改的。

#ifndef __SEQLIST_H_//防止预编译重复个定义
#define __SEQLIST_H_
typedef int SLDateType//给数据类型重定义,方便后面更改数据类型
typedef struct SeqList
{SLDateType arr[10];//变长数组int size;//数组内有效元素个数
};SL
#endif

动态顺序表

之前C语言中学习过动态内存管理,里面有个函数叫realloc:
它的作用是给动态申请的内存追加空间,动态顺序表就可以通过他来实现。

#ifndef __SEQLIST_H_//防止预编译重复个定义
#define __SEQLIST_H_
typedef int SLDateType//给数据类型重定义,方便后面更改数据类型
typedef struct SeqList
{SLDateType* arr;//这里改为指针,动态内存开辟成功后首地址给他int size;//数组内有效元素个数
};SL
#endif

动态顺序表的基本只是就介绍完了,接下来我们来实现一下动态顺序表的功能。

动态顺序表的实现

用SeqList,h头文件声明一些动态顺序表的功能函数,SeqList.c文件实现功能函数的编写,最后在test.c文件里面测试编译。

SeqList.h的创建

#ifndef __SEQLIST_H_//防止预编译重复个定义
#define __SEQLIST_H_
typedef int SLDateType//给数据类型重定义,方便后面更改数据类型
typedef struct SeqList//创建一个结构体来存放动态顺序表的起始地址
//有效数据个数以及现在的内存大小
{SLDateType* arr;//这里改为指针,动态内存开辟成功后首地址给他int capacity//动态顺序表的内存大小int size;//数组内有效元素个数
};SLvoid LS_Init(SL* ps);//初始化void LS_Destry(SL* ps);//销毁动态内存void SL_CheckCapacity(SL* ps);//检查动态内存是否已满void SL_Print(SL* ps);//打印内存有效数据void SL_PushBack(SL* ps, typedate x);//在末尾放置void SL_PushFront(SL* ps, typedate x);//在第一个位置放置void SL_Inser(SL* ps, typedate x, int pos);//在指定下标位置插入数据void SL_PopBack(SL* ps);//删除最后一位数据void SL_PopFront(SL* ps);//删除第一位数据void SL_Deser(SL* ps, int pos);//删除指定位置数据void Find(SL* ps, typedate x);//寻找某个数据的位置#endif

初始化动态顺序表(LS_Init)

void LS_Init(SL* ps)
{ps->arr=NULL;//给起始地址设置为空指针ps->size=ps->capacity=0;//数据有效个数与空间大小设为0;
}

动态顺序表的销毁(LS_Destry)

void LS_Destry(SL* ps)
{assert(ps->arr);//检查arr是否为NULLfree(ps->arr);//释放动态开辟的空间ps->arr=NULL;ps->size=ps->capacity=0;//数据有效个数与空间大小设为0;
}

检查动态内存空间是否已满(SL_CheckCapacity)

这个地方我们要用到三目操作符,防止有的人忘记或者没接触过,再介绍一下它的用法:

int m = 表达式?x:y;

当表达式成立时,就将x的值赋值给m,表达式不成立就将y的值赋值给m。

这里我们用SL_CheckCapacity满足检查内存是否够用以及第一次创建内存的操作。

void SL_CheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newdate = ps->capacity == 0 ? 4 : 2 * ps->capacity;typedate * tmp=(typedate*)realloc(ps->arr, newdate * sizeof(typedate));assert(tmp);ps->arr = tmp;ps->capacity = newdate;}
}

如果数据有效个数与内存空间大小一致,那就代表空间使用完了,就需要申请空间,所以判断一下条件是否成立。
成立后如果内存大小为0,就说明是第一次创建,我们给newdate 赋值为4,在realloc函数中创建,如果不是第一次创建,就追加一倍的空间。

动态顺序表打印有效数据(SL_Print)

void SL_Print(SL* ps)
{assert(ps);for(int i=0;i<ps->size;i++){printf("%d ",arr[i]);}
}

在末尾存放数据(SL_PushBack)

void SL_PushBack(SL* ps,typedate x)//在末位置添加数据
{assert(ps);SL_CheckCapacity(ps);ps->arr[ps->size++] = x;//放完数据后让数据有效个数+1
}

在起始位置添加有效数据(SL_PushFront)

要在第一个位置存放数据而不覆盖其他数据,就需要将数据整体后移一位。
根据最后一次移位条件:把下标为0的位置移到下标为1的位置可得for循环判定条件i>0,这样i最小是1。

void SL_PushFront(SL* ps, typedate x)//在起始位置添加有效数据
{assert(ps);SL_CheckCapacity(ps);for (int i =ps->size ; i>0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}

在指定位置添加数据(SL_Inser)

这个与在起始位置存放数据类似,将指定位置后面的数据后移一位即可。

void SL_Inser(SL* ps, typedate x,int pos)//在指定位置添加数据
{assert(ps);assert(pos >= 0 && pos <= ps->size);//保证存放的位置在开辟的空间内部SL_CheckCapacity(ps);for (int i = ps->size; i>pos; i--){ps->arr[i] = ps->arr[i - 1];  }ps->arr[pos] = x;ps->size++;
}

删除最后一位数据(SL_PopBack)

我们访问数据是基于有效数据个数访问的,直接将有效数据-1,这样我们便认为最后一个数据不是有效数据,就不会访问,跟删除效果一样。

void SL_PopBack(SL* ps)//删除最后一位数据
{assert(ps);ps->size--;
}

在起始位置删除数据(SL_PopFront)

我们将数据整体前移一位,让有效数据-1即可。

void SL_PopFront(SL* ps)
{assert(ps);                         //0 1 2 3for (int i = 0; i < ps->size-1; i++)//1 2 3 4{ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

删除任意位置的数据(SL_Deser)

这个与在起始位置删除数据一样,将指定位置后面的数据往前移一位即可。

void SL_Deser(SL* ps,int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for(int i = pos; i < ps->size-1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}

寻找内存中的某个数据的位置(Find)

void Find(SL* ps, typedate x)
{assert(ps);for (int i = 0; i < ps->size; i++){if (ps->arr[i] == x){printf("找到了,下标是%d\n", i);return 0;}}printf("找不到\n");
}

测试顺序表(test.c)

#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"int main()
{SL s;LS_Init(&s);//初始化SL_PushBack(&s, 1);//末尾放置SL_PushBack(&s, 2);//末尾放置SL_PushBack(&s, 3);//末尾放置SL_PushFront(&s, 0);//起始放置SL_Print(&s);//打印,结果应该是0 1 2 3SL_Inser(&s, 9,2);//在下标2的位置存放9SL_Print(&s);//结果:0 1 9 2 3SL_PopBack(&s);//删除末位SL_Print(&s);//结果: 0 1 9 2SL_PopFront(&s);//删除起始位SL_Print(&s);// 1 9 2SL_Deser(&s, 1);//删除下表1的数据SL_Print(&s);//1 2Find(&s, 2);//寻找2的下标LS_Destry(&s);//下标应该是1return 0;
}

在这里插入图片描述


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

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

相关文章

MySQL_数据类型建表

复习&#xff1a; 我们昨天学习的知识都忘了嘛&#xff1f;如果忘了也不要担心&#xff0c;我来带大家来复习一遍吧&#xff01;&#xff01;&#xff01; 1.查看所有数据库 show databases;2.创建属于自己的数据库 create database 数据库名; 检查自己创建的数据库是…

PHP不良事件上报系统源码,医院安全不良事件管理系统,基于 vue2+element+ laravel框架开发

不良事件上报系统通过 “事前的人员知识培训管理和制度落地促进”、“事中的事件上报和跟进处理”、 以及 “事后的原因分析和工作持续优化”&#xff0c;结合预存上百套已正在使用的模板&#xff0c;帮助医院从对护理事件、药品事件、医疗器械事件、医院感染事件、输血事件、意…

在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序

如果您有 Android 设备&#xff0c;您可能会将个人和专业的重要文件保存在设备的 SD 卡上。这些文件包括照片、视频、文档和各种其他类型的文件。您绝对不想丢失这些文件&#xff0c;但当您的 SD 卡损坏时&#xff0c;数据丢失是不可避免的。 幸运的是&#xff0c;您不需要这样…

实战:看懂并分析执行计划——Nested Loops (Inner Join)

这是执行计划中 Nested Loops 的详情信息,下面将逐行解释每个字段的含义,并提供优化思路。 Nested Loops 分析 Physical Operation: Nested Loops (Inner Join) 物理操作,表示这是一个嵌套循环连接(Nested Loops),用于执行 INNER JOIN。嵌套循环通常用于小数据集的连接…

Meta Llama3用于药物发现的微调、RAG 和提示工程-LLM保姆级资料

Meta Llama3用于药物发现的微调、RAG 和提示工程的使用指南&#xff1a;LLM微调的基本概念&#xff0c;每种微调方式的深入解读&#xff0c;2种生物医药领域的Llama3的微调应用。 LLM 如何微调LLMs&#xff1f;3种微调方式&#xff0c;什么时候&#xff1f;什么情况下该使用何…

如何通过 PXE 使用 UEFI 启动 Tiny Core Linux

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

根据关键字搜索商品API返回值解析:深入解析与代码实践

在电子商务和数据集成领域&#xff0c;API&#xff08;应用程序编程接口&#xff09;扮演着至关重要的角色。通过API&#xff0c;开发者可以访问和利用平台的数据资源&#xff0c;实现自动化和智能化的数据交互。本文将探讨如何根据关键字搜索商品API的返回值进行解析&#xff…

Python http打印(http打印body)flask demo(http调试demo、http demo、http printer)

文章目录 代码解释 代码 # flask_http_printer.pyfrom flask import Flask, request, jsonify import jsonapp Flask(__name__)app.route(/printinfo, methods[POST]) def print_info():# 分隔符separator "-" * 60# 获取请求头headers request.headers# 获取 JS…

「C/C++」C/C++ STL 之 迭代器

✨博客主页何曾参静谧的博客📌文章专栏「C/C++」C/C++程序设计📚全部专栏「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明「…

大模型微调,使用QLoRA和自定义数据集微调大模型(下)

4.8 数据预处理 在微调模型之前&#xff0c;我们不能直接使用原始数据集&#xff0c;需要将数据集中的提示转换成模型能够理解的格式。 为了使数据集适配微调流程&#xff0c;这里编写辅助函数来格式化输入数据集。具体来说&#xff0c;就是将对话摘要&#xff08;即提示-响应…

【NOIP普及组】质因数分解

【NOIP普及组】质因数分解 C语言代码C代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 已知正整数 n 是两个不同的质数的乘积&#xff0c;试求出较大的那个质数。 输入 输入只有一行&#xff0c;包含一个正整数…

js--高阶函数之参数归一化

一、前言 参数归一化&#xff1a;是我们软件开发里一个非常重要且实用的技巧&#xff0c;用的好极大简化代码同时提升代码的可阅读性和可维护性。以下我用日期格式化为例&#xff0c;演示一下参数归一化的技巧。 二、日期格式化实例 /*** 辅助格式化函数* param {string|functi…

均值、期望、方差、标准差与协方差:基础概念解析

均值、期望、方差、标准差与协方差&#xff1a;基础概念解析 在统计学和数据分析中&#xff0c;均值、期望、方差、标准差和协方差是描述数据分布和关系的基本工具。理解这些概念有助于我们更好地分析和处理数据。本文将详细讲解这些概念的定义、计算方法及其在实际应用中的意…

shell基础

一、理解bash基础 默认的Linux shell——Bash&#xff08;Bourne Again SHell&#xff09;可以通过命令控制系统&#xff0c;执行文件操作&#xff0c;或者启动应用程序。它可以在命令行上交互式使用&#xff0c;或者你可以创建一个包含多个shell命令的文件&#xff0c;并像启…

js树状结构,自叶到根统计各级数量

$($(".tree-item").get().reverse()).each(function () {let self $(this).find("span").text()let prev $(this).parent(".two").prevAll(".tree-item").find("span").text()self self ? self : 0prev prev ? prev :…

学习threejs,使用JSON格式保存和加载整个场景

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE toJSON()方法 二、&a…

论文1—《基于卷积神经网络的手术机器人控制系统设计》文献阅读分析报告

论文报告&#xff1a;基于卷积神经网络的手术机器人控制系统设计 摘要 本研究针对传统手术机器人控制系统精准度不足的问题&#xff0c;提出了一种基于卷积神经网络的手术机器人控制系统设计。研究设计了控制系统的总体结构&#xff0c;并选用PCI插槽上直接内插CAN适配卡作为上…

SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“

SLF4J常见问题 导入依赖&#xff1a; <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency> <dependency><groupId>org.slf4j</groupId><arti…

资产管理系统:SpringBoot技术驱动

4系统概要设计 4.1概述 系统设计原则 以技术先进、系统实用、结构合理、产品主流、低成本、低维护量作为基本建设原则&#xff0c;规划系统的整体构架. 先进性&#xff1a; 在产品设计上&#xff0c;整个系统软硬件设备的设计符合高新技术的潮流&#xff0c;媒体数字化、压缩、…

YOLO可视化界面,目标检测前端页面。

使用PySide6/QT实现YOLOv5/v8可视化GUI页面 在人工智能和计算机视觉领域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;是一种广泛使用的实时目标检测算法。为了直观地展示YOLO算法的检测效果&#xff0c;我们可以使用Python中的PySide6库来创建一个简单的GUI应…