详解动态顺序表

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇: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.hqwc.cn/news/315547.html

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

相关文章

复兴计划01-lc06

StringBuilder和StringBuffer的区别 1. StringBuffer和StringBuilder都是用于字符串动态拼接,但是StringBuffer拼接的函数方法的实现中用了synchornized上锁&#xff0c;效率较低&#xff0c;不过可以用于多线程以此来维护线程安全&#xff1b;相比之下&#xff0c;StringBuil…

odoo17后台启动过程4——odoo.http.root

在上一篇文章中&#xff0c;我们再启动server的时候传入了一个对象odoo.http.root&#xff0c;看看这是何方神圣 odoo\http.py 这里定义了Application类&#xff0c; 二root是这个类的一个实例&#xff0c;注释说这是WSGI网关的入口点。通过调试跟踪&#xff0c;也确定了 odoo…

线程池的两种提交方式

线程池是一种并发编程的机制&#xff0c;用于管理和重用线程&#xff0c;以提高应用程序的性能和效率。Java中的ExecutorService是线程池的一个接口&#xff0c;它提供了两种主要的方法来提交任务&#xff1a;execute()和submit()。 1. execute() 方法&#xff1a; void execut…

IP tables防火墙(一)

本章主要介绍&#xff1a; 熟悉Linux防火墙的表&#xff0c;链的结构理解数据包匹配的基本流程学会编写IP tables规则 1.0防火墙基础 在 Internet 中&#xff0c;企业通过架设各种应用系统来为用户提供各种网络服务&#xff0c;如 Web 网站、电子邮件系统、FTP 服务器、数…

教你用策略枚举消除if-else判断(以支付场景为例子)带给你新的认知,记得收藏哦~

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

TDD-LTE 附着流程和去附着流程

目录 1. 附着流程 1.1. 正常附着流程 2. 异常附着流程 2.1 RRC建立失败 2.2 核心网拒绝 2.3 eNodeB未收到初始化上下文建立请求 2.4 RRC重配置请求丢失 2. 去附着流程 2.1 非关机去附着流程 2.1.1 连接态非关机去附着 2.1.2 空闲态非关机去附着 2.2 关机去附着流程 …

【algorithm】自动驾驶常见常考的几个模型和推导,顺便总结自己遇到的考题经验不断更新之———控制版

写在前面 本来快达成目标了&#xff0c;没想到公司遭受了问题&#xff0c;公司和同事我感觉还是挺好的&#xff0c;有国企的正规也有小企业的灵活&#xff0c;大家都很有学习欲望。 作为本次再次复习回忆如下&#xff1a; 把之前面试准备的 机器学习&#xff08;基本搬运到CSD…

车载 Android之 核心服务 - CarPropertyService 的VehicleHAL

前言: 本文是车载Android之核心服务-CarPropertyService的第二篇&#xff0c;了解一下CarPropertyService的VehicleHAL, 第一篇在车载 Android之 核心服务 - CarPropertyService 解析-CSDN博客&#xff0c;有兴趣的 朋友可以去看下。 本节介绍 AndroidAutomotiveOS中对于 Veh…

什么是软件测试?这是我听过最通俗易懂的解释

很多人总是说我要学习软件测试&#xff0c;因为他可以拿到一个不错的薪资。 但是当我问他你知道什么是软件测试吗&#xff1f;这个时候&#xff0c;他总会愣住了&#xff0c;一脸不屑的表情说着&#xff0c;不就是找bug&#xff0c;给软件找问题&#xff0c;找茬吗&#xff1f…

混合编程—C++程序中python脚本的嵌入方法(理论部分)

一、C与Python高级编程语言简概 &#xff08;一&#xff09;C C是一种被广泛使用的计算机程序设计语言。它是一种通用程序设计语言&#xff0c;支持多重编程范式&#xff0c;例如过程化程序设计&#xff08;Procedural programming&#xff09;、面向对象程序设计&#xff08;…

CISSP 第1章:实现安全治理的原则和策略

作者&#xff1a;nothinghappend 链接&#xff1a;https://zhuanlan.zhihu.com/p/669881930 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 CIA CIA 三性&#xff1a; 机密性&#xff1a;和数据泄露有关。完整性…

odoo17 | 模型和基本字段

前言 在上一章的最后&#xff0c;我们能够创建一个Odoo模块。然而&#xff0c;在这一点上&#xff0c;它仍然是一个空壳&#xff0c;不允许我们这样做 存储任何数据。在我们的房地产模块中&#xff0c;我们希望存储与 数据库中的属性&#xff08;名称、描述、价格、居住面积等…