首页 > 其他分享 >Day02 顺序表

Day02 顺序表

时间:2024-06-15 16:02:33浏览次数:20  
标签:count 顺序 return int Day02 sq data

目录

1、顺序表

2、随机访问&顺序访问

3、思考

4、顺序表的封装


1、顺序表

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

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

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

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

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

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

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

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

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

2、随机访问&顺序访问

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

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

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

3、思考

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

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

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

4、顺序表的封装

/****************************************************
 * @file     顺序表.c
 * @brief    顺序表的实现
 * @author    [email protected]
 * @date      2024-6-15
 * @version   V1.0
 * @note
 *          数组下标从0开始,到size-1结束;
 *          数组下标从0开始,有效元素个数为count,则最后一个元素的下标是count-1;
 *          从末尾插入元素时,count+1,如果count==size,则需要扩容;
 *          从末尾删除元素时,count-1,如果count==size,则需要缩容;
 * @history
 *      Date        Version    Author           Notes
 *      2024-6-15   0.0.1    zuozhenxing    first version
 * Copyright (c) 2024,[email protected] All rights reserved.
 ***********************************************/

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// 1.定义顺序表数据类型
typedef int ElemType;
// 2.设计一个顺序表结构体
typedef struct Sqlist
{
    ElemType *data; // 保存数据首地址
    int count;      // 保存存储的数据个数
    int size;       // 保存容量
} Sqlist_t;

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

/*********************createSq*****************************
 * @function:createSq
 * @brief:创建一个顺序表
 * @param
 *      size 顺序表的容量
 * @return
 *      Sqlist_t* 返回顺序表结构体指针
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:notes
 * @history:
 *      Date        Version    Author           Notes
 *      2020-04-26   0.0.1    demon_xing     first version
 * *******************END****************************/
// 1.创建一个顺序表
Sqlist_t *createSq(int size)
{
    // (1)申请结构体空间
    Sqlist_t *sq = (Sqlist_t *)malloc(sizeof(Sqlist_t));
    if (sq == NULL)
    {
        return NULL;
    }

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

/*********************destroySq*****************************
 * @function:destroySq
 * @brief:销毁顺序表
 * @param
 *      sq 顺序表结构体指针
 * @return
 *      void
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:notes
 * @history:
 *      Date        Version      Author              Notes
 *      2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
// 2.销毁顺序表
void destroySq(Sqlist_t *sq)
{
    // (1)如果sq为NULL,则直接返回
    if (sq == NULL)
    {
        return;
    }
    // (2)如果sq不为NULL,则释放数据空间和结构体空间
    // 释放数据空间
    free(sq->data);
    // 释放结构体空间
    free(sq);
}

/*********************insertSq*****************************
 * @function:insertSq
 * @brief:在指定位置插入数据
 * @param
 *      sq 顺序表结构体指针
 *      data 插入的数据
 *      pos 插入的位置
 * @return
 *      bool 插入成功返回true,否则返回false
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:
 *      插入数据后,count++
 * @history:
 *      Date        Version    Author           Notes
 *     2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
// 3.在指定位置插入数据
bool insertSq(Sqlist_t *sq, ElemType data, int pos)
{
    //(1)判断sq是否为空,如果为空,则直接返回false,如果不为空,则继续执行
    if (sq == NULL || pos < 0)
    {
        perror("顺序表为NULL");
        return false;
    }
    // (2)判断顺序表是否已满,如果已满,则直接返回false,如果不满,则继续执行
    if (sq->count == sq->size)
    {
        perror("顺序表满");
        return false;
    }

    // (3)判断pos是否在0-count中间,如果在就要进行挪位,如果不在0-count中间就直接插入末尾
    // pos不在0-count中间,末尾插入
    if (pos >= sq->count)
    {
        // 把数据放在pos位置,因为pos是最后一个位置,所以直接放在count位置,数组从0开始计数
        sq->data[sq->count] = data;
        // 插入数据后,count++
        sq->count++;
    }
    // pos在0-count中间,需要进行挪位
    else
    {
        for (int i = sq->count; i > pos; i--)
        {
            // pos以后的数据后移一位
            sq->data[i] = sq->data[i - 1];
        }
        // (4)把数据放在pos位置
        sq->data[pos] = data;
        // (5)插入数据后,count++
        sq->count++;
    }
    return true;
}
/*********************indexSq*****************************
 * @function:indexSq
 * @brief:查询数据
 * @param
 *      sq 顺序表结构体指针
 *      data 查询的数据
 * @return
 *      int 返回数据位置下标,没找到返回-1
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:notes
 * @history:
 *      Date        Version    Author           Notes
 *     2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
// 4.查询数据
int indexSq(Sqlist_t *sq, ElemType data)
{
    // (1)遍历数组, 查到就返回数组下标,查不到就返回-1
    if (sq == NULL)
    {
        perror("顺序表为NULL,请先创建");
        return -1; // 没找到数据
    }

    for (int i = 0; i < sq->count; i++)
    {
        if (sq->data[i] == data)
        {
            return i; // 找到数字,返回该数据的下标
        }
    }
    return -1;
}

/*********************deleteSq*****************************
 * @function:deleteSq
 * @brief:删除数据
 * @param
 *      sq 顺序表结构体指针
 *      data 删除的数据
 * @return
 *      bool 删除成功返回true,否则返回false
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:
 *      删除数据之后,count--
 * @history:
 *      Date        Version    Author           Notes
 *      2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
// 5.删除数据
bool deleteSq(Sqlist_t *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;
}
/*********************displaySq*****************************
 *
 * @function:displaySq
 * @brief:遍历显示
 * @param
 *      sq 顺序表结构体指针
 * @return
 *      void
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:notes
 * @history:
 *      Date        Version      Author              Notes
 *      2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
// 遍历显示

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

/*********************main*****************************
 * @function:main
 * @brief:主函数,测试顺序表
 * @param
 *      void
 * @return
 *      int
 * @author: demon_xing
 * @date:2024-6-15
 * @version:V1.0
 * @note:notes
 * @history:
 *      Date        Version    Author           Notes
 *      2020-04-26   0.0.1     demon_xing      first version
 * **********************END*************************/
int main(void)
{
    // 1.创建顺序表
    Sqlist_t *sq = createSq(10);
    // 2.插入数据
    for (int i = 0; i < 10; i++)
    {
        int data = random() % 100;
        insertSq(sq, data, i);
    }
    // 3.显示
    displaySq(sq);
    // 4.删除数据
    deleteSq(sq, 21);
    // 5.显示
    displaySq(sq);
    // 6.销毁
    destroySq(sq);
    // 7.显示,如果段错误,说明销毁成功,否则销毁失败
    displaySq(sq);
    // 也可以用valgrind内存检测工具或内存泄漏检测器来证所有的内存已经被正确释放,确保没有内存泄漏。

    return 0;
}

标签:count,顺序,return,int,Day02,sq,data
From: https://blog.csdn.net/qq_59111928/article/details/139663953

相关文章

  • 支付宝签名和验签使用JSONObject是最优解。json字符串顺序和==符号都一致演示代码
    支付宝签名和验签使用JSONObject是最优解。json字符串顺序和==符号都一致演示代码支付宝spi接口设计验签和返回结果加签注意点,支付宝使用JSONObject对象https://www.cnblogs.com/oktokeep/p/18249346packagecom.example.core.mydemo;importcom.alibaba.fastjson.JSON;imp......
  • 利用信号量实现线程顺序执行
    线程顺序循环执行的场景在多线程编程中并不罕见,尤其是在需要协调多个线程按特定顺序重复执行任务的情况下。以下是几个常见的例子:生产者-消费者模型:在这种模型中,生产者线程生成数据并将其放入缓冲区,而消费者线程从缓冲区取出数据进行处理。这种情况下,生产者和消费者线程通常按顺......
  • 数据结构:手撕代码——顺序表
     目录 1.线性表2.顺序表2.1顺序表的概念2.2动态顺序表实现 2.2-1动态顺序表实现思路2.2-2动态顺序表的初始化 2.2-3动态顺序表的插入检查空间 尾插头插 中间插入 2.2-4 动态顺序表的删除 尾删头删 中间删除 2.2.5动态顺序表查找与打印、销毁......
  • 数据结构(C/C++)专题一:顺序表与链表
    今天开始一个新的专题:数据结构当然,不仅仅适用于学习也适用于408考研。那么提起数据结构思维导图:总结如下:·1.初识顺序表与链表首先呢我们要明白,数据结构有物理结构,也有逻辑结构物理结构就是电脑实际的结构,链式,非链式,索引,散列eg:链式结构(LinkedStructure)例子:火车车......
  • ArrayList顺序表简单实现
    一、创建MyArrayList框架 1.1MyArrayList类中实现 arr数组importjava.util.Arrays;publicclassMyArrayList{privateint[]arr;privateintusesize;privatestaticfinalintP=10;publicMyArrayList(){arr=newint[P];......
  • 【数据结构】【版本1.0】【线性时代】——顺序表
    快乐的流畅:个人主页个人专栏:《算法神殿》《数据结构世界》《进击的C++》远方有一堆篝火,在为久候之人燃烧!文章目录引言一、顺序表的概念1.1最基础的数据结构:数组1.2数组与顺序表的区别二、静态顺序表三、动态顺序表的模拟实现3.1定义3.2初始化3.3......
  • springboot rabbitmq如何保证消息顺序消费
    很多时候,消息的消费是不用保证顺序的,比如借助mq实现订单超时的处理。但有些时候,业务中可能会存在多个消息需要顺序处理的情况,比如生成订单和扣减库存消息,那肯定是先执行生成订单的操作,再执行扣减库存的操作。那么这种情况下,是如何保证消息顺序消费的呢?首先,为了效率,我们可以设置......
  • 小宋的SpringCloud学习记录day02
    基于Restful风格实现下列接口:今天我们继续昨天的课程来学习一下MybatisPlus的核心功能——IService接口下面是我们需要在pom文件中要引入的依赖<!--swagger--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-sta......
  • Jmeter元件执行顺序和作用域
    执行顺序配置元件前置处理器定时器取样器后置处理器断言监听器注意:   1.前置、后置处理器和断言等元件对取样器作用,如果在他们的作用域内没有任何取样器,则不会执行。   2.如果在同一作用域范围内有多个同一类型的元件,则这些元件按照他们在测试计划中的上下顺序......
  • 【OJ】链表的按顺序排序
    题目描述~~~将带有头结点的单向链表结点中的数据从小到大排序。输入描述第一行输入链表长度;第二行输入链表结点中的数据。输出描述排序后的链表(输出头结点,用“Head”表示)用例输入160104286用例输出1Head->0->2->4->6->8->10code:#include<stdio.h>......