纯c实现顺序表 数据结构大全

        我们已经知道数组是连续的内存地址,顺序表是由数组为基础的一种数据结构,拥有比数组更多的功能,在概念上属于线性结构,跟链表不同的是,顺序表在物理结构上也是线性的

        什么是数据结构? 当我们想要使⽤⼤量使⽤同⼀类型的数据时,通过手动定义⼤量的独立的变量对于程序来说,可读性非常差,我们可以借助数组这样的数据结构将⼤量的数据组织在⼀起,结构也可以理解为组织数据的方式。

        数组就是一种最为简单的数据结构,但是数组有着其局限性。

        求数组的⻓度,求数组的有效数据个数,随意变化数组的大小,向下标为数据有效个数的位置插⼊数据。假设数据量⾮常庞⼤,频繁的获取数组有效数据个数会影响程序执⾏效率。结论:最基础的数据结构能够提供的操作已经不能完全满⾜复杂算法实现。

        

        接着我带大家,来实现一个这样的数据结构,体会其特点

        我们先要定义一个结构体来存储数据,这里我们先默认存的数据是整形,(这个不同的需求很容易修改存储的数据类型),我们在这里定义名字为sl简化后面的代码

定义

struct dplist//动态 更常用
{int* a;int size;//有效数据个数;int capa;//顺序表当前大小
}sl;

初始化 

 然后是顺序表的初始化,正常操作

void begin(struct dplist* sl)//初始化
{sl->a = NULL;sl-> size = 0;sl-> capa = 0;
}

定义 

这里是定义,调用前面的begin函数

void sltest()//定义
{struct dplist sl;begin(&sl);
}

开辟内存 

然后是重要的检查空间跟有效数据个数,以此判断空间是否足够,是不是要多开辟的函数,后面的接口也会大量用到这个

这里采用的是两倍两倍的开辟新内存空间的方法

void checkcapa(struct dplist* sl)//检查空间是否足够 不够的话自动扩容
{if (sl->size == sl->capa){int newcapa = sl->capa == 0 ? 4 : 2 * sl->capa;struct dplist* tmp = (struct dplist*)realloc(sl->a, newcapa * sizeof(struct dplist));if (tmp == NULL){perror("fall");return ;}sl->a = tmp;sl->capa = newcapa;//因为本来sl->capa为0,所以定义newcapa}
}

销毁 

然后是数据结构经典的销毁函数,避免内存泄漏

void destroy(struct dplist* sl) //销毁空间,不要浪费
{if (sl->a)free(sl->a);sl->a = NULL;sl->capa = 0;sl->size = 0;
}

尾插 

然后是简单的尾插函数,记得把有效数据个数的size++

void pushback(struct dplist* sl,int x)//尾插
{//assert(sl)if (sl == NULL)//比assert柔和的方式{return;}//判断空间checkcapa(sl);//sl已经是指针了,直接传//插入数据 注意size的指向 要指向下一个,因为后面还要插sl->a[sl->size] = x;sl->size++;
}

头插 

然后是头插,把所有数据都向后移一位

void pushfront(struct dplist* sl,int x)//头插 历史数据后移
{if (sl == NULL){return;}//判断空间checkcapa(sl);//直接调用函数//后移历史数据for (int i = sl->size; i > 0; i--){sl->a[i] = sl->a[i - 1];}//头插sl->a[0] = x;sl->size++;
}

尾删 

然后是尾删接口,直接size--就可以,因为下一次size++的时候这个位置会赋值新的数了

void popback(struct dplist* sl)//尾删
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}sl->size--;//在size的数据如果下次size到这里就会覆盖掉
}

头删 

然后是头删,数据集体向前移动来覆盖

void popfront(struct dplist* sl)//头删 数据直接向左移动来覆盖
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//向左移动for (int i = 0; i < sl->size ; i++){sl->a[i] = sl->a[i + 1];}
}

 指定位置插入数据

然后是指定位置插入数据

一样是把指定的位置后面的数据向后移动就可以了

void slinsert(struct dplist* sl, int pos, int x)//指定位置插入数据 pos为下标
{if (sl == NULL){return;}checkcapa(sl);//把pos及后面的数据向后挪for (int i = sl->size; i > pos; i--){sl->a[i] = sl->a[i - 1];}//对pos加以限制,避免程序崩溃if (pos < 0 || pos > sl->size){return;}//注意size的值 因为又插入了值sl->a[pos] = x;sl->size++;
}

 指定位置删除数据

与指定位置插入数据相对应的就是指定位置删除数据,让其后面的数据向前移动覆盖就可以了

void sldelete(struct dplist* sl, int pos)//指定位置删除数据 也是覆盖 往前移动
{//经典判断if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//对pos加以限制,避免程序崩溃if (pos < 0 || pos >= sl->size){return;}//往前覆盖for (int i = pos; i < sl->size - 1; i++){sl->a[i] = sl->a[i + 1];}sl->size--;//数据减少
}

 查找数据是否存在

然后是查找数据是否存在,简单遍历就可以了

int slfind(struct dplist* sl,int x)//查找数据是否存在 存在返回1 否则-1
{// 经典判断if (sl == NULL){return;}for (int i = 0; i < sl->size; i++){if (sl->a[i] == x){return 1;}}return -1;
}

打印顺序表 

然后是打印函数,可以检查前面的操作正不正确

void slprint(struct dplist* sl)//打印顺序表 看操作是否正确
{for (int i = 0; i < sl->size; i++){printf("%d ", sl->a[i]);}printf("\n");
}

最后给出完整代码

#define _CRT_SECURE_NO_WARNINGS//顺序表  静态和动态
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "sep.h"struct seplist//静态
{int aa[100];int size;//有效数据个数
};struct dplist//动态 更常用
{int* a;int size;//有效数据个数;int capa;//顺序表当前大小
}sl;void begin(struct dplist* sl)//初始化
{sl->a = NULL;sl-> size = 0;sl-> capa = 0;
}
void sltest()//定义
{struct dplist sl;begin(&sl);
}
void destroy(struct dplist* sl) //销毁空间,不要浪费
{if (sl->a)free(sl->a);sl->a = NULL;sl->capa = 0;sl->size = 0;
}
void checkcapa(struct dplist* sl)//检查空间是否足够 不够的话自动扩容
{if (sl->size == sl->capa){int newcapa = sl->capa == 0 ? 4 : 2 * sl->capa;struct dplist* tmp = (struct dplist*)realloc(sl->a, newcapa * sizeof(struct dplist));if (tmp == NULL){perror("fall");return ;}sl->a = tmp;sl->capa = newcapa;//因为本来sl->capa为0,所以定义newcapa}
}
void pushback(struct dplist* sl,int x)//尾插
{//assert(sl)if (sl == NULL)//比assert柔和的方式{return;}//判断空间checkcapa(sl);//sl已经是指针了,直接传//插入数据 注意size的指向 要指向下一个,因为后面还要插sl->a[sl->size] = x;sl->size++;
}
void pushfront(struct dplist* sl,int x)//头插 历史数据后移
{if (sl == NULL){return;}//判断空间checkcapa(sl);//直接调用函数//后移历史数据for (int i = sl->size; i > 0; i--){sl->a[i] = sl->a[i - 1];}//头插sl->a[0] = x;sl->size++;
}
void popback(struct dplist* sl)//尾删
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}sl->size--;//在size的数据如果下次size到这里就会覆盖掉
}
void popfront(struct dplist* sl)//头删 数据直接向左移动来覆盖
{if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//向左移动for (int i = 0; i < sl->size ; i++){sl->a[i] = sl->a[i + 1];}
}
void slinsert(struct dplist* sl, int pos, int x)//指定位置插入数据 pos为下标
{if (sl == NULL){return;}checkcapa(sl);//把pos及后面的数据向后挪for (int i = sl->size; i > pos; i--){sl->a[i] = sl->a[i - 1];}//对pos加以限制,避免程序崩溃if (pos < 0 || pos > sl->size){return;}//注意size的值 因为又插入了值sl->a[pos] = x;sl->size++;
}
void sldelete(struct dplist* sl, int pos)//指定位置删除数据 也是覆盖 往前移动
{//经典判断if (sl == NULL){return;}//判断是否已经为空if (sl->size == 0){return;}//对pos加以限制,避免程序崩溃if (pos < 0 || pos >= sl->size){return;}//往前覆盖for (int i = pos; i < sl->size - 1; i++){sl->a[i] = sl->a[i + 1];}sl->size--;//数据减少
}
int slfind(struct dplist* sl,int x)//查找数据是否存在 存在返回1 否则-1
{// 经典判断if (sl == NULL){return;}for (int i = 0; i < sl->size; i++){if (sl->a[i] == x){return 1;}}return -1;
}
void slprint(struct dplist* sl)//打印顺序表 看操作是否正确
{for (int i = 0; i < sl->size; i++){printf("%d ", sl->a[i]);}printf("\n");
}
int main()
{return 0;
}

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

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

相关文章

云计算平台建设总体技术方案详细参考

第1章. 基本情况 1.1. 项目名称 XX 公司 XX 云计算平台工程。 1.2. 业主公司 XX 公司。 1.3. 项目背景 1.3.1. XX 技术发展方向 XX&#xff0c;即运用计算机、网络和通信等现代信息技术手段&#xff0c;实现政府组织结构和工作流程的优化重组&#xff0c;超越时间、空间…

开源28181协议视频平台搭建流程

最近项目中用到流媒体平台&#xff0c;java平台负责信令部分&#xff0c;c平台负责流媒体处理&#xff0c;找了评分比较好的开源项目 https://gitee.com/pan648540858/wvp-GB28181-pro 流媒体服务基于 c写的 https://github.com/ZLMediaKit/ZLMediaKit 说明文档&#xff1a;h…

Visual Studio Code常用设置

此处用于记录下本人所使用 VScode 的使用习惯。其中主要包括&#xff1a;界面&#xff0c;主题&#xff0c;光标&#xff0c;文件保存等选项。 VSCode 用户区设置 相关介绍命令行方式进行配置可视化组件方式进行配置 更新 相关介绍 基本原理&#xff1a; Visual Studio Code 会…

【电子通识】各国电源插头标准和电压标准

在使用仪器时&#xff0c;通常会在使用之前去看下规格书。比如安装指南、快速使用指南等等来提取我们需要的信息。 一般大型的仪器供应商会卖往不同的国家&#xff0c;所以都会配置多种电源线。如下所示规格书中对仪器的电源线种类进行了说明。其中有中国、美国、加拿大、日本…

设计模式入门

0. 类图 1. 设计原则 1.单一职责原则&#xff1a;每个类只有一个功能 2.开放封闭原则&#xff1a;模块和函数应该对扩展开放(对提供方)&#xff0c;对修改关闭(对使用方) 3.里氏代换原则&#xff1a;子类拥有父类的所有方法和属性&#xff0c;从而可以减少创建类的工作量 4.依…

20240115在ubuntu20.04.6下给GTX1080M显卡安装驱动程序和CUDA

20240115在ubuntu20.04.6下给GTX1080M显卡安装驱动程序和CUDA 2024/1/15 18:05 百度搜索&#xff1a;ubuntu gtx1080m cuda https://blog.csdn.net/wb4916/article/details/129462103 20230311给Ubuntu18.04下的GTX1080M安装驱动 https://www.cnblogs.com/djiankuo/p/5886605.h…

每日一练:LeeCode-144、145、94.二叉树的前中后序遍历【二叉树】

本文是力扣LeeCode-144、145、94.二叉树的前中后序遍历 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode前序遍历、中序遍历、后序遍历。 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序遍历。 给定一个二叉树的根…

概率论与数理统计————3.随机变量及其分布

一、随机变量 设E是一个随机试验&#xff0c;S为样本空间&#xff0c;样本空间的任意样本点e可以通过特定的对应法则X&#xff0c;使得每个样本点都有与之对应的数对应&#xff0c;则称XX&#xff08;e&#xff09;为随机变量 二、分布函数 分布函数&#xff1a;设X为随机变量…

C# wpf 实现任意控件(包括窗口)更多调整大小功能

WPF拖动改变大小系列 第一节 Grid内控件拖动调整大小 第二节 Canvas内控件拖动调整大小 第三节 窗口拖动调整大小 第四节 附加属性实现拖动调整大小 第五章 拓展更多调整大小功能&#xff08;本章&#xff09; 文章目录 WPF拖动改变大小系列前言一、添加的功能1、任意控件Drag…

Flink 处理函数(1)—— 基本处理函数

在 Flink 的多层 API中&#xff0c;处理函数是最底层的API&#xff0c;是所有转换算子的一个概括性的表达&#xff0c;可以自定义处理逻辑 在处理函数中&#xff0c;我们直面的就是数据流中最基本的元素&#xff1a;数据事件&#xff08;event&#xff09;、状态&#xff08;st…

基于SSM的项目监管系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

xtdrone用键盘控制无人机飞行 无法起飞

运行案例 解锁无人机螺旋桨转动但无法起飞 也未报错 解决方法&#xff1a; 在QGC中修改&#xff1a;PX4飞控EKF配置 将PX4使用的EKF配置为融合GPS的水平位置与气压计高度。 如果我们想使用视觉定位&#xff0c;就需要把修改配置文件。 此修改意味着EKF融合来自mavros/vision_…

基于SSM的网上招聘系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

AtCoder Beginner Contest 336 G. 16 Integers(图计数 欧拉路径转欧拉回路 矩阵树定理 best定理)

题目 给16个非负整数&#xff0c;x[i∈(0,1)][j∈(0,1)][k∈(0,1)][l∈(0,1)] 求长为n3的01串的方案数&#xff0c;满足长度为4的ijkl&#xff08;2*2*2*2&#xff0c;16种情况&#xff09;串恰为x[i][j][k][l]个 答案对998244353取模 思路来源 https://www.cnblogs.com/tz…

Go后端开发 -- 数组 slice map range

Go后端开发 – 数组 && slice && map && range 文章目录 Go后端开发 -- 数组 && slice && map && range一、数组1.数组的声明和初始化2.数组的传参 二、slice切片1.slice的定义和初始化2.len()和cap()函数3.空切片4.切片截取5…

【计算机组成与体系结构Ⅱ】指令调度与分支延迟(实验)

实验4&#xff1a;指令调度与分支延迟 一、实验目的 1. 加深对指令调度技术的理解。 2. 加深对分支延迟技术的理解。 3. 熟练采用指令调度技术解决流水线中的数据冲突的方法。 4. 进一步理解指令调度技术对CPU性能的改进。 5. 进一步理解延迟分支技术对CPU性能的改进。 二…

装完32G内存条 电脑飞跃提升!

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 大家…

MiniTab的拟合回归模型的分析

拟合回归模型概述 使用拟合回归模型和普通最小二乘法可以描述一组预测变量和一个连续响应之间的关系。可以包括交互作用项和多项式项、执行逐步回归和变换偏斜数据。 例如&#xff0c;房地产评估人员想了解城市公寓与多个预测变量&#xff08;包括建筑面积、可用单元数量、建…

【YOLO系列】 YOLOv4之Focal Loss损失函数

论文下载&#xff1a;Focal Loss for Dense Object Detection 一、简介 Focal Loss损失函数何凯明大神在RetinaNet网络中提出来的&#xff0c;主要是为了解决one-stage目标检测中正负样本比例严重失衡的问题。该损失函数降低了大量简单负样本在训练中所占的比重&#xff0c;也可…

安装Anaconda遇到的问题

报错如下&#xff1a; Anaconda3 5.1.0(64-bit) Setup Error:Due to incompatibility with several Pyth on libraries, Destination Folder’cannot contain non-ascii characters(special characters or diacritics). Please choose another location. 原因&#xff1a;安装…