详解动态顺序表

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk

      ⸝⋆   ━━━┓
     - 个性标签 - :来于“云”的“羽球人”。 Talk is cheap. Show me the code
┗━━━━━━━  ➴ ⷯ

本人座右铭 :   欲达高峰,必忍其痛;欲戴王冠,必承其重。

👑💎💎👑💎💎👑 
💎💎💎自💎💎💎
💎💎💎信💎💎💎
👑💎💎 💎💎👑    希望在看完我的此篇博客后可以对你有帮助哟

👑👑💎💎💎👑👑   此外,希望各位大佬们在看完后,可以互赞互关一下,看到必回
👑👑👑💎👑👑👑     

目录 

一:顺序表的介绍

  1:顺序表定义

    顺序表是线性表的一种,首先顺序表是是用一段物理地址连续的存储单元依次存储数据元素的线性结构,多数情况下借助数组来存储

二:动态顺序表和静态顺序表区别

  1:静态顺序表:

   静态就体现了静态顺序表的特征,数组的空间大小是固定的

//静态顺序表的结构体的构造
#define N 10
typedef int SLDataTYpe;//便于实现各种数据类型,一改全改typedef struct SeqList
{SLDataTYpe a[N];int size;//记录数据有效的个数
}SL;
 2:动态顺序表

 动态体现了是一个不断变化的过程,可以频繁进行扩容

//动态顺序表
typedef int SLDataType;//便于实现各种数据类型,一改全改
typedef struct SeqList
{SLDataType* a;int size;//记录数据有效的个数int capacity;//空间空间的容量
}SL;
3:二者区别

静态顺序表:以定长数组的形式存储

动态顺序表:以动态开辟的数组进行存储

本质上二者没有优劣之分,只不过动态顺序表多了一个成员:空间容量

三:动态顺序表的接口实现

1. 初始化

为了避免不必要的麻烦,我们在初始化的时候直接就对数组进行动态开辟

void SLInit(SL* psl)
{assert(psl);psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//先为数组开4 个空间if (psl->a == NULL)  //空间检查{printf("perror malloc\n");return;}// 开辟成功psl->size = 0;psl->capacity = 4;
}
2.销毁
void SLDestroy(SL* psl)
{assert(psl);free(psl->a);psl->a = NULL;psl->capacity = 0;psl->size = 0;
}
3.尾插

分析:首先我们在尾插之前需要先进行空间容量检查

 

void SLPushBack(SL* psl, SLDataType x)
{assert(psl);//先判断空间是否足够CheckCapacity(psl);//之后直接尾插psl->a[psl->size] = x;psl->size++;
}
4.头插

分析:

1)空间容量的检查

2) 数据的挪动:从后往前挪动(避免数据覆盖)

3)下标边界值的确定

 

void SLPushFront(SL* psl, SLDataType x)
{assert(psl);//先判断空间是否足够CheckCapacity(psl);挪动数据:从后往前挪动数据 注意边界的问题int end = psl->size - 1;while (end >= 0){psl->a[end + 1] = psl->a[end];end--;}psl->a[0] = x;psl->size++;
}
 5.尾删

先进行判空,其次直接size--

void SLPopBack(SL* psl)
{assert(psl);//判断是否为空   温柔  / 暴力判断if (psl->size == 0){printf("为空 \n");return;}psl->size--;}
6.头删

先进行判空

其次挪动数据:从前往后挪动

下标边界的确定

 

void SLPopFront(SL* psl)
{assert(psl);assert(psl->size);//判空// 挪动数据:从前往后挪数据int start = 0;while (start < psl->size - 1){psl->a[start] = psl->a[start + 1];start++;}//SLEarse(psl, 0);//注意:别忘了size--psl->size--;}
7.任意位置的插入

1)空间容量检查

2)pos这个位置是否合法

3)数据挪动:和头插一样

 

void SLInsert(SL* psl, int pos, SLDataType x)
{assert(psl);// 先进行空间判断,以及位置的合法CheckCapacity(psl);assert(pos >= 0 && pos <= psl->size);  //这里可以取等,因为数组下标是连续的,可以在psl->size 这个位置插入int i = psl->size - 1;while (i >= pos){psl->a[i + 1] = psl->a[i];i--;}psl->a[pos] = x;psl->size++;// 灵活运用: 头插,尾插就是此函数的一个特列}
8.任意位置的删除

1)判空检查

2)pos是否合法

3)数据挪动:同头删一样

 

void SLEarse(SL* psl, int pos)
{assert(psl);//删除之前,先对pos这个位置判断是否合法,是否为空assert(pos >= 0 && pos < psl->size);  //注意这里没有必要取等  ,同时这个语句暗含着对判空的操作了int i = pos;//挪动数据:从前往后while (i < psl->size - 1){psl->a[i] = psl->a[i + 1];i++;}//别忘了 size--psl->size--;}

9.空间容量的检查

    当我们在进行头插,尾插,任意位置插入时都需要进行空间容量的检查,这里为了避免不必要的麻烦,写了一个函数

void CheckCapacity(SL* psl)
{assert(psl);if (psl->capacity == psl->size){//realloc来扩容   void* realloc (void* ptr, size_t size);  第二个参数:扩容之后新的空间字节数,而不是要增加的字节数// 注意这样写是错误的,在free 的时候有问题  SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) *  4) * 2);//以原来2倍空间扩容SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) * psl->capacity) * 2);//以原来2倍空间扩容if (tmp == NULL){printf("perror realloc\n");return;}// 扩容成功,进行更新psl->a = tmp;psl->capacity *= 2;}
}
10. 查找

1)前期的判断:位置是否合法?  顺序表是否为空表

2) 其实就是暴力求解,依次遍历顺序表即可,若是找到返回下标找不到返回-1

int  SLFind(SL* psl, SLDataType x)//查找
{assert(psl);assert(psl->size);//避免为空int i = 0;while (i < psl->size){if (psl->a[i] == x){return i;// 返回下标}i++;}return -1;//没有找到
}

11.任意位置修改 

1)依然是老生常谈,对位置以及顺序表进行判断

2)直接进行修改

void SLModify(SL* psl, int pos, SLDataType x) //指定位置修改
{assert(psl);assert(psl->size);//避免为空assert(pos >= 0 && pos <= psl->size - 1);psl->a[pos] = x;}

完整代码:

SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"void SLInit(SL* psl)
{assert(psl);psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//先为数组开4 个空间if (psl->a == NULL){printf("perror malloc\n");return;}psl->size = 0;psl->capacity = 4;
}
void SLDestroy(SL* psl)
{assert(psl);free(psl->a);psl->a = NULL;psl->capacity = 0;psl->size = 0;
}
void CheckCapacity(SL* psl)
{assert(psl);if (psl->capacity == psl->size){//realloc来扩容   void* realloc (void* ptr, size_t size);  第二个参数:扩容之后新的空间字节数,而不是要增加的字节数// 注意这样写是错误的,在free 的时候有问题  SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) *  4) * 2);//以原来2被空间扩容SLDataType* tmp = (SLDataType*)realloc(psl->a, (sizeof(SLDataType) * psl->capacity) * 2);//以原来2被空间扩容if (tmp == NULL){printf("perror realloc\n");return;}// 扩容成功,进行更新psl->a = tmp;psl->capacity *= 2;}
}
void SLPushBack(SL* psl, SLDataType x)
{assert(psl);//先判断空间是否足够CheckCapacity(psl);//之后直接尾插/*psl->a[psl->size] = x;psl->size++;*/if (psl->size == 0){psl->a[psl->size] = x;psl->size++;}else{SLInsert(psl, psl->size, x);//注意这里不用size++,因为SLInsert这个函数以及涉及到了}
}
void SLPushFront(SL* psl, SLDataType x)
{assert(psl);//先判断空间是否足够CheckCapacity(psl);挪动数据:从后往前挪动数据 注意边界的问题//int end = psl->size - 1;//while (end >= 0)//{//	psl->a[end + 1] = psl->a[end];//	end--;//}//psl->a[0] = x;SLInsert(psl, 0, x);// psl->size++;
}
void SLPopBack(SL* psl)
{assert(psl);//判断是否为空   温柔  / 暴力判断/*if (psl->size == 0){printf("为空 \n");return;}*/assert(psl->size);psl->size--;}
void SLPopFront(SL* psl)
{assert(psl);assert(psl->size);//判空// 挪动数据:从前往后挪数据int start = 0;while (start < psl->size - 1){psl->a[start] = psl->a[start + 1];start++;}//SLEarse(psl, 0);//注意:别忘了size--psl->size--;}
void SLPrint(SL* psl)
{assert(psl);int i = 0;while (i < psl->size){printf("%d ", psl->a[i]);i++;}printf("\n");
}
void SLEarse(SL* psl, int pos)
{assert(psl);//删除之前,先对pos这个位置判断是否合法,是否为空assert(pos >= 0 && pos < psl->size);  //注意这里没有必要取等  ,同时这个语句暗含着对判空的操作了int i = pos;//挪动数据:从前往后while (i < psl->size - 1){psl->a[i] = psl->a[i + 1];i++;}//别忘了 size--psl->size--;}
void SLInsert(SL* psl, int pos, SLDataType x)
{assert(psl);// 先进行空间判断,以及位置的合法CheckCapacity(psl);assert(pos >= 0 && pos <= psl->size);  //这里可以取等,因为数组下标是连续的,可以在psl->size 这个位置插入int i = psl->size - 1;while (i >= pos){psl->a[i + 1] = psl->a[i];i--;}psl->a[pos] = x;psl->size++;// 灵活运用: 头插,尾插就是此函数的一个特列}
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>//顺序表分类:静态顺序表  动态顺序表//静态的:空间开大了浪费,空间开小了不够用/*静态顺序表的结构体的构造
#define N 10
typedef int SLDataTYpe;//便于实现各种数据类型,一改全改typedef struct SeqList
{SLDataTYpe a[N];int size;//记录数据有效的个数
}SL;
*///动态顺序表
typedef int SLDataType;//便于实现各种数据类型,一改全改
typedef struct SeqList
{SLDataType* a;int size;//记录数据有效的个数int capacity;//空间空间的容量
}SL;
//接口函数的实现void SLInit(SL* psl);
void SLDestroy(SL* psl);
void SLPushBack(SL* psl, SLDataType x);
void SLPushFront(SL* psl, SLDataType x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);
void SLPrint(SL* psl);
void SLEarse(SL* psl,int pos);
void SLInsert(SL* psl, int pos, SLDataType x);

结束语:

以上就是我今日要为大家分享的,希望各位大佬随时指正,咱一波关注走起,看到必回

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

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

相关文章

前端:html+css+js实现CSDN首页

提前说一下&#xff0c;只实现了部分片段哈&#xff01;如下&#xff1a; 前端&#xff1a;htmlcssjs实现CSDN首页 1. 实现效果2. 需要了解的前端知识3. 固定定位的使用4. js 监听的使用4. 参考代码和运行结果 1. 实现效果 我的实现效果为&#xff1a; 原界面如下,网址为&…

LLM Agent零微调范式 ReAct Self Ask

前三章我们分别介绍了思维链的使用&#xff0c;原理和在小模型上的使用。这一章我们正式进入应用层面&#xff0c;聊聊如何把思维链和工具使用结合得到人工智能代理。 要回答我们为什么需要AI代理&#xff1f;代理可以解决哪些问题&#xff1f;可以有以下两个视角 首先是我们…

三层架构概述

三层架构就是把整个软件的代码分为三个层次&#xff0c;分层的目的是&#xff1a;规范代码&#xff0c;大型软件需要团队配合的时候问题就来了&#xff0c;由于每个程序员风格不一样&#xff0c;而开发软件大量的代码风格不统一就会造成后期调试和维护出现问题&#xff0c;然而…

Squid 代理服务器

13.1.1缓存代理概述 作为应用层的代理服务软件&#xff0c;Squid主要提供缓存加速、应用层过滤控制的功能。 1.代理的工作机制 当客户机通过代理来请求Web页面时&#xff0c;指定的代理服务器会先检查自己的缓存&#xff0c;如果缓存中已 经有客户机需要的页面&#xff0c;则直…

Udp实现一个小型shell

实现原理 首先我们要有个客户端和一个服务器&#xff0c;客户端向服务器传递命令。而服务器收到命令后创建一个管道&#xff0c;并fork一个子进程。随后子进程解析命令&#xff0c;再把标准输出换成管道文件&#xff0c;因为命令行命令是自动输出到显示器的&#xff0c;所以我…

英飞凌TC3xx之一起认识GTM系列(一)先来认识GTM架构

英飞凌TC3xx之一起认识GTM系列(一)先来认识GTM架构 1 先来认识GTM的通用架构2 概览2.1 架构的简要说明2.2 架构概述1 先来认识GTM的通用架构 GTM系统使用GTM全局时钟fGTM 运行(本文称为SYS_CLK)。 特点如下: GTM模块由两个主要部分组成: 由博世设计的GTM IP v3.1.5.1 …

【Java 数组解析:探索数组的奇妙世界】

数组的引入 我们先通过一段简单的代码引入数组的概念。 import java.util.Scanner; public class TestArray01{public static void main(String[] args){//功能&#xff1a;键盘录入十个学生的成绩&#xff0c;求和&#xff0c;求平均数&#xff1a;//定义一个求和的变量&…

【我与CSDN的128天】相识相知相守

目录: 相识相知相守 相识 为什么选择写博客? 写博客的目的,我觉得是因为想要记录。记录学习的过程,整理学过的知识,方便今后的复习。 更重要的是热爱分享,分享给别人知识也是一种快乐。 在某一瞬间教会某一个你不认识的人,难道不是一个很酷的事情吗? 为什么选择CSDN? 作…

企业签名分发对移动应用开发者有什么影响

企业签名分发是移动应用开发者在应用程序发布前测试、内部分发和特定的受众群体分发等方面比较常用的一种工具。那对于应用商城分发有啥区别&#xff0c;下面简单的探讨一下。 独立分发能力 通过企业签名分发开发者可以自己决定应用程序的发布时间和方式&#xff0c;不用受应用…

[2024区块链开发入门指引] - 比特币运行原理

一份为小白用户准备的免费区块链基础教程 工欲善其事,必先利其器 Web3开发中&#xff0c;各种工具、教程、社区、语言框架.。。。 种类繁多&#xff0c;是否有一个包罗万象的工具专注与Web3开发和相关资讯能毕其功于一役&#xff1f; 参见另一篇博文&#x1f449; 2024最全面…

Android14之禁掉Selinux的两种方式(一百七十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

uniapp的分包使用记录

UniApp的分包是一种将应用代码划分为多个包的技术。分包的核心思想是将不同部分的代码划分为不同的包&#xff0c;按需加载&#xff0c;从而提高应用性能。使用UniApp的条件编译功能&#xff0c;开发人员可以根据需要将代码划分为多个包。每个包都包含一组页面和组件&#xff0…

大数据Doris(四十五):物化视图选择最优

文章目录 物化视图选择最优 物化视图选择最优 下面详细解释一下第一步最优物化视图是被如何选择出来的。 这里分为两个步骤: 对候选集合进行一个过滤。只要是查询的结果能从物化视图数据计算(取部分行,部分列,或部分行列的聚合)出都可以留在候选集中,过滤完成后候选集合…

RocketMQ源码解析-主从同步原理(HA)

1、关键组件 主从同步的实现逻辑主要在HAService中&#xff0c;在它的构造函数中实例化了几个对象同时在start()方法内执行启动&#xff1a; public class HAService {public HAService(final DefaultMessageStore defaultMessageStore) throws IOException {this.defaultMes…

李宏毅机器学习第二十三周周报 Flow-based model

文章目录 week 23 Flow-based model摘要Abstract一、李宏毅机器学习1.引言2.数学背景2.1Jacobian2.2Determinant2.3Change of Variable Theorem 3.Flow-based Model4.GLOW 二、文献阅读1. 题目2. abstract3. 网络架构3.1 change of variable formula3.2 Coupling layers3.3Prop…

阿里云域名外部入库流程

注册商是阿里云&#xff0c;且在阿里云管理的&#xff0c;请使用此教程外部入库。 如您的域名注册商是阿里云但在聚名管理&#xff0c;请参考教程&#xff1a;https://www.west.cn/faq/list.asp?unid2539 在外部入库操作之前&#xff0c;请先登录阿里云获取账号ID。详细的账…

软件测试方法分类-按照是否手工执行划分

接上一篇,下来我们再细讲,第二个维度的分类, 软件测试方法分类-按照是否手工执行划分 按是否手工执行划分 1,手工测试(manualTesting) 手工测试是由人一个一个的输入用例,然后观察结果,和机器测试相对应,属于比较原始但是必须的一种。 2,自动化测试(automationTestin…

【刷题日志】深度理解除(/)与取模(%)附水仙花数以及变种水仙花数题解

文章目录 &#x1f680;前言&#x1f680;除与取模&#x1f680;水仙花数&#x1f680;变种水仙花数 &#x1f680;前言 本专栏文章都直奔刷题主题&#xff0c;阿辉都不会在废话了&#xff0c;加油&#xff0c;少年&#xff01;&#xff01;&#xff01; &#x1f680;除与取…

STM32CubeMX教程11 RTC 实时时钟 - 入侵检测和时间戳

目录 1、准备材料 2、实验目标 3、实验流程 3.0、前提知识 3.1、CubeMX相关配置 3.1.1、时钟树配置 3.1.2、外设参数配置 3.1.3、外设中断配置 3.2、生成代码 3.2.1、外设初始化调用流程 3.2.2、外设中断调用流程 3.2.3、添加其他必要代码 4、常用函数 5、烧录验…

探索 CodeWave低代码技术的魅力与应用

目录 前言1 低代码平台2 CodeWave简介3 CodeWave 的独特之处3.1 高保真还原交互视觉需求3.2 擅长复杂应用开发3.3 支持应用导出&独立部署3.4 金融级安全要求3.5 可集成性高3.6 可拓展性强 4 平台架构和核心功能4.1 数据模型设计4.2 页面设计4.3 逻辑设计4.4 流程设计4.5 接…