Day02 顺序表

news2024/12/23 20:38:25

目录

1、顺序表

2、随机访问&顺序访问

3、思考

4、顺序表的封装


1、顺序表

        数组在数据结构中是属于线性表的一种,线性表是由一组具有n个相同类型的数据元素组成的。线性表中的任何一个数据元素

  • 有且只有一个直接前驱
  • 有且只有一个直接后继
  • 首元素是没有前驱的
  • 尾元素是没有后继的

  • 某个元素的左侧相邻元素被称为“直接前驱”,
  • 元素左侧所有的数据元素被称为“前驱元素”。
  • 某个元素的右侧相邻元素被称为“直接后继”,
  • 元素右侧所有的数据元素被称为“后继元素”。

        满足这种数学关系的一组元素,逻辑关系就是线性结构,并且逻辑关系是一对一的,比如一个教室学生的学号、一个排队的队伍、一摞堆好的盘子.....都属于线性结构,当然线性结构和存储方式是无关的,简单理解:只有逻辑关系是一对一的,就是线性结构。

所以,根据数据的存储方式可以把线性表分为两种

  • 顺序存储的线性表
  • 链式存储的线性表。

        顺序表指的是使用一组内存地址连续的内存单元来依次存储线性表中的数据元素,使用这种存储结构的线性表就被称为顺序表。

简单理解:数据存储在一块连续的内存中,在C语言中可以具名的数组,也可以使用匿名的数组(堆内存)。

顺序表的特点:数据元素之间的逻辑关系是相邻的,并且内存地址也是相邻的,所以只要知道存储线性表的第一个数据元素的内存地址,就可以对线性表中的任意一个元素进行随机访问。通常用户使用动态分配的数组来实现顺序表,也就是使用堆内存实现。

2、随机访问&顺序访问

        随机访问指的是在同等时间内具有访问任意元素的能力

  • 随机访问相对立的就是顺序访问
  • 顺序访问花费的时间要高于随机访问

比如卷轴(顺序)和书籍(随机)、磁带(顺序)和唱片(随机)。

3、思考

思考:既然数组可以作为线性表来使用,请问如何对数组中的元素进行增加和删除以及访问?

回答:如果打算使用数组实现线性表的特性,需要知道三个条件:

  1. 数组首元素地址address;
  2. 数组元素的容量size;
  3. 数组中元素的个数count。

4、顺序表的封装

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//设计数据元素类型
typedef int ElemType;

// 设计一个顺序表节点结构体
struct Sqlist
{
    ElemType *data; // 保存数据首地址
    int count;      // 保存存储的数据个数
    int size;       // 保存容量
};

// 创建一个顺序表
struct Sqlist *createSq(int size);
// 销毁顺序表
void destroySq(struct Sqlist *sq);
// 在指定位置插入数据
bool insertSq(struct Sqlist *sq, ElemType data, int pos);
// 查询数据--返回数据位置,没找到返回-1
int indexSq(struct Sqlist *sq, ElemType data);
// 删除数据
bool deleteSq(struct Sqlist *sq, ElemType data);
// 遍历显示
void displaySq(struct Sqlist *sq);

// 创建一个顺序表
struct Sqlist *createSq(int size)
{
    // 1.申请结构体空间
    struct Sqlist *sq = (struct Sqlist *)malloc(sizeof(struct Sqlist));
    if (sq == NULL)
    {
        return NULL;
    }

    // 2.初始化结构体成员,
    sq->size = size;
    sq->count = 0;
    // 3.申请数据空间
    sq->data = malloc(sizeof(ElemType)*(sq->size));
    if (sq->data == NULL)
    {
        // 数据空间申请失败,则将其结构体空间释放
        free(sq);
        return NULL;
    }
    // 4.返回结构体指针
    return sq;
}

// 销毁顺序表
void destroySq(struct Sqlist *sq)
{
    if (sq == NULL)
    {
        return;
    }
    // 1.释放数据空间
    free(sq->data);
    // 2.释放结构体空间
    free(sq);
}

// 在指定位置插入数据
bool insertSq(struct Sqlist *sq, ElemType data, int pos)
{
    // 1.判断sq是否为空,count与size是否相等(满)
    if (sq == NULL)
    {
        perror("顺序表为NULL");
         return false;
    }

    if (sq->count == sq->size || pos < 0)
    {
        perror("顺序表满");
        return false;
    }

    // 2.判断pos是否在0-count中间,那么就要进行挪位,如果不在0-count中间就直接插入末尾
    if (pos >= sq->count)
    {
        sq->data[sq->count] = data;
        sq->count++;
    }
    else
    {
        for (int i = sq->count; i > pos; i--)
        {
            sq->data[i] = sq->data[i - 1];
        }
        // 3.把数据放在pos位置
        sq->data[pos] = data;
        // 4.count++
        sq->count++;
    }
    return true;
}
// 查询数据--返回数据位置,没找到返回-1
int indexSq(struct Sqlist *sq, ElemType data)
{
    // 遍历数组, 查到就返回数组下标
    if (sq == NULL)
    {
        return -1;
    }
    for (int i = 0; i < sq->count; i++)
    {
        if (sq->data[i] == data)
        {
            return i;
        }
    }
    return -1;
}
// 删除数据
bool deleteSq(struct Sqlist *sq, ElemType data)
{
    // 1.调用indexSq查询
    int pos = indexSq(sq, data);
    if (pos == -1)
    {
        return false;
    }
    // 2.挪位删除
    for (int i = pos; i < sq->count - 1; i++)
    {
        sq->data[i] = sq->data[i + 1];
    }
    // 3.count--
    sq->count--;
    return true;
}

// 遍历显示
void displaySq(struct Sqlist *sq)
{
    // 遍历数组输出
    if (sq == NULL)
    {
        return;
    }
    for (int i = 0; i < sq->count; i++)
    {
        printf("%d ", sq->data[i]);
    }
    printf("\n");
}

int main(void)
{
    // 创建顺序表
    struct Sqlist *sq = createSq(10);
    // 插入数据
    for (int i = 0; i < 11; i++)
    {
        int data = random() % 100;
        insertSq(sq, data, i);
    }
    // 显示
    displaySq(sq);
    // 销毁
    destroySq(sq);
}

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

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

相关文章

学习Java中的Future类

学习Java中的Future类 Future接口在Java 5中引入&#xff0c;作为java.util.concurrent包的一部分。它代表一个异步计算的结果&#xff0c;当计算完成时可以通过Future对象获取结果。Future对象提供了一些方法来检查任务是否完成、等待任务完成并获取任务结果、取消任务等。 …

【python】tkinter编程三大布局管理器pack、grid、place应用实战解析

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

leetcode240 搜索二维矩阵II

题目 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18…

redis序列化

文章目录 1、为什么要进行序列化操作&#xff1f;2、序列化方式2.1、自定义序列化2. 2、StringRedisTemplate&#xff08;重点&#xff09; 1、为什么要进行序列化操作&#xff1f; 不进行序列化向redis存入数据代码&#xff1a; SpringBootTest class RedisDemoApplicationT…

渗透测试练习题解析 6 (CTF web)

1、[HCTF 2018]admin 1 考点&#xff1a;二次注入 先注册一个账号看看&#xff0c;注册 admin 会提示该用户名已存在&#xff0c;那我们就换一个用户名 观察页面功能&#xff0c;存在一个修改密码&#xff0c;开始的思路是想看看能否通过该密码功能抓包然后修改用户名为 admin …

RAG_Example

今天尝试基于langchain进行LLM RAG搭建&#xff0c;感觉使用难度没有想象中大。具体流程参考末尾链接。 主要流程包括下面几个模块&#xff0c;每一个模块都有很多选择&#xff0c;而不是唯一解。 但这里可以感受到潜在的几个问题 1. 文本转换过程中&#xff0c;PDF的信息可…

Android framework的Zygote源码分析

文章目录 Android framework的Zygote源码分析linux的fork Android framework的Zygote源码分析 init.rc 在Android系统中&#xff0c;zygote是一个native进程&#xff0c;是Android系统上所有应用进程的父进程&#xff0c;我们系统上app的进程都是由这个zygote分裂出来的。zyg…

极限网关助力好未来 Elasticsearch 容器化升级

极限网关在好未来的最佳实践案例&#xff0c;轻松扛住日增百 TB 数据的流量&#xff0c;助力 ES 从物理机到云原生架构的改造&#xff0c;实现了流控、请求分析、安全管理、无缝迁移等场景。一次完美的客户体验~ 背景 物理机架构时代 2022 年&#xff0c;好未来整个日志 Elas…

开源AGV调度系统OpenTCS中的路由器(router)详解

OpenTCS中的任务分派器router详解 1. 引言2. 路由器(router)2.1 代价计算函数&#xff08;Cost functions&#xff09;2.2 2.1 Routing groups2.1 默认的停车位置选择2.2 可选停车位置属性2.3 默认的充电位置选择2.4 即时运输订单分配 3. 默认任务分派器的配置项4. 参考资料与源…

区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测

区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现EVO-CNN-SVM能量谷算法优化卷积神经网络支持向量机结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资…

Java——IO流(一)-(4/8):前置知识-字符集、UTF-8、GBK、ASCII、乱码问题、编码和解码等

目录 常见字符集介绍 标准ASCII字符集 GBK&#xff08;汉字内码扩展规范&#xff0c;国标&#xff09; Unicode字符集&#xff08;统一码&#xff0c;万国码&#xff09; 小结 字符集的编码、解码操作 方法 实例演示 常见字符集介绍 标准ASCII字符集 ASCll(American St…

python数据分析--- ch8-9 python函数及类

python数据分析--- ch8-9 python函数及类 1. Ch8--函数1.1 函数的定义1.2 形参与实参1.2.1 使用位置参数调用函数1.2.2 使用关键字参数调用函数 1.3 参数的默认值1.4 可变参数(*)1.4.1 基于元组的可变参数(* 可变参数)1.4.2 基于字典的可变参数(** 可变参数) 1.5 函数中变量的作…

【PHP开发工程师系统性教学】——thinkPHP的分页操作,不管有几页,用这个你想分几页就分几页

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

【单片机毕业设计选题24005】-基于STM32的智能家居环境监测系统

系统功能: 此设计采用STM32单片机将采集到的环境环境温湿度,光照强度,火焰传感器状态,烟雾值,空气质量值等数据显示在OLED上&#xff0c;并将这些信息通过上报至手机APP。系统可通过手机蓝牙APP修改各传感器阈值. 蓝牙连接后&#xff0c;如果系统处于自动状态则每隔5秒钟上报…

多表联查小情景例子

这里有个需求&#xff1a; 需要给定套餐表setmeal 的 id 查询这个套餐内的所有菜品 dish 实际上如果可能&#xff0c;只需要查询套餐菜品表(setmeal_dish)&#xff0c;查看一个套餐内包含包含的所有菜品&#xff0c;然后把这些菜品全部取出即可。 看一下setmeal_dish 表&…

水泥行业超低排放简介

在当今社会&#xff0c;随着环保意识的不断提高&#xff0c;水泥行业作为重要的工业领域&#xff0c;其超低排放的实施范围及成效日益受到人们的关注。朗观视觉小编将从多个角度探讨水泥行业超低排放的实施范围&#xff0c;分析其背后的意义与影响&#xff0c;展望未来的发展趋…

LogicFlow 学习笔记—7. LogicFlow 基础 背景 Background

背景 Background 提供可以修改画布背景的方法&#xff0c;包括背景颜色或背景图片&#xff0c;背景层位于画布的最底层。 info 创建画布时&#xff0c;通过 background 选项来设置画布的背景层样式&#xff0c;支持透传任何样式属性到背景层。默认值为 false 表示没有背景。 …

Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测(股票价格预测)

目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测&#xff08;股票价格预测&#xff09; 模型设计 融合Adaboost的CNN-LSTM模型的时间序列预测&#xff0c;下面是一个基本的框架。 …

软件性能测试基本概述

大家好&#xff0c;在性能测试的世界里&#xff0c;确保软件系统的高效运行至关重要。性能测试不仅仅是为了评估软件系统的性能&#xff0c;更是为了保障用户体验、提高系统稳定性和可靠性。本文将带您一览性能测试的基本概述&#xff0c;从性能测试的定义、重要性&#xff0c;…

【踩坑】修复Ubuntu远程桌面忽然无法Ctrl C/V复制粘贴及黑屏

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 说在前面&#xff1a; 需要注意的是&#xff0c;我发现他应该是新开了一个窗口给我。我之前打开的东西&#xff0c;在这个新窗口里都没有了&#xff0c…