数据结构---动态数组

 一、数据结构基本理论

数据结构是相互之间存在一种或多种特定关系的数据元素的集合。强调数据元素之间的关系

算法五个特性:
        输入、输出、有穷、确定、可行

数据结构分类:
        逻辑结构:集合、线性结构、树形结构、图形结构

        物理结构:顺序存储、链式存储、索引存储、散列存储(哈希存储)

二、动态数组实现

1.设计

        struct dynamicArray

        属性:
        void ** pAddr  维护真实在堆区创建的数组的指针

        int capacity;  数组容量·
        int m_size;  数组大小

2.动态数组初始化

struct dynamicArray* init_DynamicArray(int capacity);

3.插入数组

void insert_DynamicArray(struct dynamicArray* array, int pos, void* data);

4.遍历数组

void foreach_DynamicArray(struct dynamicArray* array, void(*myPrint)(void*));

5.删除数组

按位置删除

void removeByPos_DynamicArray(struct dynamicArray* array, int pos);

按值删除数据

void removeByValue_DynamicArray(struct dynamicArray* array, void* data, int(*myCompare)(void*, void*));

6.销毁数组

void destroy_DynamicArray(struct dynamicArray* array);

代码如下: 

#define _CRT_SECURE_NO_WARNINGS  
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//动态数组结构体
struct dynamicArray
{void** pAddr;//维护真实在堆区创建的数组的指针int m_capacity;//数组容量int m_size;//数组大小
};//初始化数组
struct dynamicArray* init_DynamicArray(int capacity)
{if (capacity <= 0){return NULL;}//给数组分配空间struct dynamicArray* array = malloc(sizeof(struct dynamicArray));if (array == NULL){return NULL;}array->pAddr = malloc(sizeof(void*) * capacity);array->m_capacity = capacity;array->m_size = 0;return array;
};//插入数据
void insert_DynamicArray(struct dynamicArray *array,int pos,void *data)
{if (array == NULL) {return;}if (data == NULL){return;}//无效位置	尾插if (pos < 0 || pos > array->m_size){pos = array->m_size;}//判断是否满了,如果满了动态扩展if (array->m_size == array->m_capacity){//1.申请更大的内存空间int newCapacity = array->m_capacity * 2;//2.创建空间void** newSpace = malloc(sizeof(void*) * newCapacity);//3.将原有的数据拷贝到新空间下memcpy(newSpace, array->pAddr, sizeof(void*) * array->m_capacity);//4.释放原有内存空间free(array->pAddr);//5.更新新空间指向array->pAddr = newSpace;//6.更新新容量array->m_capacity = newCapacity;}//插入新元素//移动元素	进行插入新元素 for (int i = array->m_size - 1; i >= pos; i--){//数据向后移动array->pAddr[i + 1] = array->pAddr[i];}//将新元素插入到指定位置上array->pAddr[pos] = data;//更新大小array->m_size++;
};//遍历数组
void foreach_DynamicArray(struct dynamicArray* array,void(*myPrint)(void *))
{if (array == NULL){return;}if (myPrint == NULL){return;}for (int i = 0; i < array->m_size; i++){myPrint(array->pAddr[i]);}
}//删除数组	按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos)
{if (NULL == array){return;}if (pos < 0 || pos > array->m_size - 1){return;}//数据前移for (int i = pos; i < array->m_size - 1; i++){array->pAddr[i] = array->pAddr[i + 1];}//更新数组大小array->m_size--;}	//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray *array,void *data,int(* myCompare)(void *,void *))
{if (array == NULL){return;}if (data == NULL){return;}for (int i = 0; i < array->m_size; i++){if (myCompare(array->pAddr[i], data)){//如果找到要删除的数据,i就是要删除的具体位置removeByPos_DynamicArray(array, i);break;}}
}//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)
{if (array == NULL){return;}if (array->pAddr != NULL){free(array->pAddr);array->pAddr = NULL; }free(array);array = NULL;
}//测试
struct Person
{char name[64];int age;
};void myPrintPerson(void* data)
{struct Person* p = data;printf("姓名:%s 年龄:%d\n", p->name, p->age);
}int myComparePerson(void *data1, void *data2)
{struct Person* p1 = data1;struct Person* p2 = data2;return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
int main()
{//初始化动态数组struct dynamicArray* array = init_DynamicArray(5);//准备数据struct Person p1 = { "亚瑟",18 };struct Person p2 = { "妲己",20 };struct Person p3 = { "安其拉",19 };struct Person p4 = { "凯",21 };struct Person p5 = { "孙悟空",999 };struct Person p6 = { "李白",999 };printf("插入数据前容量:%d 大小:%d\n", array->m_capacity, array->m_size);//插入数据insert_DynamicArray(array, 0, &p1);insert_DynamicArray(array, 0, &p2);insert_DynamicArray(array, 1, &p3);insert_DynamicArray(array, 0, &p4);insert_DynamicArray(array, -1, &p5);insert_DynamicArray(array, 2, &p6);//凯  妲己  李白  安其拉  亚瑟  孙悟空//遍历数组foreach_DynamicArray(array, myPrintPerson);printf("插入数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);//测试删除	按位置删除removeByPos_DynamicArray(array, 2);printf("-------------------\n");foreach_DynamicArray(array, myPrintPerson);printf("删除数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);struct Person p = { "亚瑟",18 };removeByValue_DynamicArray(array, &p,myComparePerson);printf("-------------------\n");foreach_DynamicArray(array, myPrintPerson);printf("删除数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);//销毁数组destroy_DynamicArray(array);array = NULL;return 0;
}

三、实现分文件编写 

dynamicArray.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS  
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//动态数组结构体
struct dynamicArray
{void** pAddr;//维护真实在堆区创建的数组的指针int m_capacity;//数组容量int m_size;//数组大小
};//初始化数组
struct dynamicArray* init_DynamicArray(int capacity);//插入数据
void insert_DynamicArray(struct dynamicArray* array, int pos, void* data);//遍历数组
void foreach_DynamicArray(struct dynamicArray* array, void(*myPrint)(void*));//删除数组	按位置删除
void removeByPos_DynamicArray(struct dynamicArray* array, int pos);//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray* array, void* data, int(*myCompare)(void*, void*));//销毁数组
void destroy_DynamicArray(struct dynamicArray* array);

dynamicArray.c

#include"dynamicArray.h"//初始化数组
struct dynamicArray* init_DynamicArray(int capacity)
{if (capacity <= 0){return NULL;}//给数组分配空间struct dynamicArray* array = malloc(sizeof(struct dynamicArray));if (array == NULL){return NULL;}array->pAddr = malloc(sizeof(void*) * capacity);array->m_capacity = capacity;array->m_size = 0;return array;
};//插入数据
void insert_DynamicArray(struct dynamicArray *array,int pos,void *data)
{if (array == NULL) {return;}if (data == NULL){return;}//无效位置	尾插if (pos < 0 || pos > array->m_size){pos = array->m_size;}//判断是否满了,如果满了动态扩展if (array->m_size == array->m_capacity){//1.申请更大的内存空间int newCapacity = array->m_capacity * 2;//2.创建空间void** newSpace = malloc(sizeof(void*) * newCapacity);//3.将原有的数据拷贝到新空间下memcpy(newSpace, array->pAddr, sizeof(void*) * array->m_capacity);//4.释放原有内存空间free(array->pAddr);//5.更新新空间指向array->pAddr = newSpace;//6.更新新容量array->m_capacity = newCapacity;}//插入新元素//移动元素	进行插入新元素 for (int i = array->m_size - 1; i >= pos; i--){//数据向后移动array->pAddr[i + 1] = array->pAddr[i];}//将新元素插入到指定位置上array->pAddr[pos] = data;//更新大小array->m_size++;
};//遍历数组
void foreach_DynamicArray(struct dynamicArray* array,void(*myPrint)(void *))
{if (array == NULL){return;}if (myPrint == NULL){return;}for (int i = 0; i < array->m_size; i++){myPrint(array->pAddr[i]);}
}//删除数组	按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos)
{if (NULL == array){return;}if (pos < 0 || pos > array->m_size - 1){return;}//数据前移for (int i = pos; i < array->m_size - 1; i++){array->pAddr[i] = array->pAddr[i + 1];}//更新数组大小array->m_size--;}	//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray *array,void *data,int(* myCompare)(void *,void *))
{if (array == NULL){return;}if (data == NULL){return;}for (int i = 0; i < array->m_size; i++){if (myCompare(array->pAddr[i], data)){//如果找到要删除的数据,i就是要删除的具体位置removeByPos_DynamicArray(array, i);break;}}
}//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)
{if (array == NULL){return;}if (array->pAddr != NULL){free(array->pAddr);array->pAddr = NULL; }free(array);array = NULL;
}

测试:

#define _CRT_SECURE_NO_WARNINGS  
#include<stdio.h>
#include<string.h>
#include<stdlib.h>#include"dynamicArray.h"//测试
struct Person
{char name[64];int age;
};void myPrintPerson(void* data)
{struct Person* p = data;printf("姓名:%s 年龄:%d\n", p->name, p->age);
}int myComparePerson(void *data1, void *data2)
{struct Person* p1 = data1;struct Person* p2 = data2;return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
}
int main()
{//初始化动态数组struct dynamicArray* array = init_DynamicArray(5);//准备数据struct Person p1 = { "亚瑟",18 };struct Person p2 = { "妲己",20 };struct Person p3 = { "安其拉",19 };struct Person p4 = { "凯",21 };struct Person p5 = { "孙悟空",999 };struct Person p6 = { "李白",999 };printf("插入数据前容量:%d 大小:%d\n", array->m_capacity, array->m_size);//插入数据insert_DynamicArray(array, 0, &p1);insert_DynamicArray(array, 0, &p2);insert_DynamicArray(array, 1, &p3);insert_DynamicArray(array, 0, &p4);insert_DynamicArray(array, -1, &p5);insert_DynamicArray(array, 2, &p6);//凯  妲己  李白  安其拉  亚瑟  孙悟空//遍历数组foreach_DynamicArray(array, myPrintPerson);printf("插入数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);//测试删除	按位置删除removeByPos_DynamicArray(array, 2);printf("-------------------\n");foreach_DynamicArray(array, myPrintPerson);printf("删除数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);struct Person p = { "亚瑟",18 };removeByValue_DynamicArray(array, &p,myComparePerson);printf("-------------------\n");foreach_DynamicArray(array, myPrintPerson);printf("删除数据后容量:%d 大小:%d\n", array->m_capacity, array->m_size);//销毁数组destroy_DynamicArray(array);array = NULL;return 0;
}

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

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

相关文章

安装nginx-1.25.5与ngx_http_headers_more_filter_module模块

#下载nginx的代码 curl -O http://nginx.org/download/nginx-1.25.5.tar.gz #下载headers-more-nginx-module代码 git clone https://github.com/openresty/headers-more-nginx-module#解压 tar -xzf nginx-1.25.5.tar.gzcd nginx-1.25.5#--add-dynamic-module 下载下来的目录 …

接入大量设备后,视频汇聚系统EasyCVR安防监控视频融合平台是如何实现负载均衡的?

一、负载均衡 随着技术的不断进步和监控需求的日益增长&#xff0c;企业视频监控系统的规模也在不断扩大&#xff0c;接入大量监控设备已成为一项常态化的挑战。为确保企业能够有效应对这一挑战&#xff0c;视频汇聚系统EasyCVR视频融合平台凭借其卓越的高并发处理能力&#x…

“Postman 中文版使用教程:如何切换到中文界面?”

Postman 的很好用的接口测试软件。但是&#xff0c;Postman 默认是英文版的&#xff0c;也不支持在软件内切换为中文版。很多同学的英语并不是很好&#xff0c;看到一堆的英文很是头痛。 今天我们来介绍下&#xff1a;切换到 Postman 中文版的方法。想要学习更多的关于 Postma…

【教学类-50-14】20240505“数一数”图片样式12:数一数(12个“人物”图案)

作品展示 背景需求&#xff1a; 前文做了“”材料”图片的数一数学具&#xff0c;效果不错&#xff0c; https://blog.csdn.net/reasonsummer/article/details/138466325https://blog.csdn.net/reasonsummer/article/details/138466325 为了让图案内容更丰富&#xff0c;我又…

皮秒激光切割机可以切割材料及主要应用行业

皮秒激光切割机可以切割多种材料&#xff0c;主要应用行业包括但不限于&#xff1a; 1. PCB板行业&#xff1a;主要用于PCB激光分板&#xff0c;如FR4、补强钢片、FPC、软硬结合板、玻纤板等材料的紫外激光切割。 2. 薄膜材料切割&#xff1a;皮秒紫外激光切割机可以直接切割薄…

启英泰伦“离线自然说”技术,让智能语音芯片更善解人意

“以科技创新推动产业创新&#xff0c;特别是以颠覆性技术和前沿技术催生新产业、新模式、新动能&#xff0c;发展新质生产力”。2023年12月&#xff0c;中央经济工作会议强调了发展新质生产力的路径。“科技创新是发展新质生产力的核心要素&#xff0c;这也是我们一直潜心在做…

解决Pyppeteer下载chromium慢或者失败的问题[INFO] Starting Chromium download.

文章目录 1.进入网址2.选择上面对应自己系统的文件夹进去3. 然后找到自己的python环境中的site-packages中pyppeteer中的chromium_downloader.py文件并打开 在首次使用Pyppeteer时需要下载chromium 1.进入网址 https://registry.npmmirror.com/binary.html?pathchromium-bro…

07_Flutter使用NestedScrollView+TabBarView滚动位置共享问题修复

07_Flutter使用NestedScrollViewTabBarView滚动位置共享问题修复 一.案发现场 可以看到&#xff0c;上图中三个列表的滑动位置共享了&#xff0c;滑动其中一个列表&#xff0c;会影响到另外两个&#xff0c;这显然不符合要求&#xff0c;先来看下布局&#xff0c;再说明产生这个…

【MM32F3270 Micropython】pwm输出

文章目录 前言一、PWM脉宽调制技术介绍二、machine.PWM 类2.1 machine.PWM 类的构造对象2.2 PWM 对象初始化2.3 关闭PWM设备2.4 设置pwm的周期2.5 设置占空比 三、pwm示例代码总结 前言 MicroPython是一种精简的Python 3编程语言实现&#xff0c;旨在在微控制器和嵌入式系统上…

算法分析 KMP算法中next值的计算、0/1背包问题

5.6.1 KMP算法中next值的计算 设模式的长度为m。用蛮力法求解 KMP算法中的 next值时&#xff0c;next[0]可直接给出&#xff0c;计算next[j](1<j<m-1)则需要在 T[0] …T[j-1]中分别取长度为j-1、..、2、1的真前缀和真后缀并比较是否相等&#xff0c;最坏情况下的时间代价…

解析Linux键盘组合键产生信号的完整过程:从硬件中断到信号发送

前言 每一个了解Linux的都知道这样一个知识&#xff0c;CtrlC组合键能够终止一个进程。 个人了解进程相关知识之后知道&#xff0c;一个进程被终止只会有有三种情况&#xff1a; 代码运行完毕&#xff0c;结果正确代码运行完毕&#xff0c;结果不正确代码运行异常&#xff…

鸿蒙OpenHarmony【基于Hi3516DV300开发板(时钟应用开发)】

概述 本文将介绍如何快速搭建基于OpenHarmony标准系统&#xff08;Hi3516DV300开发板&#xff09;的应用开发环境&#xff0c;并基于一个时钟APP示例逐步展示应用的创建、开发、调试和安装等流程。示例代码可以通过本链接获取。 时钟App是一款显示实时时间的应用&#xff0c;…

【GDPU】数据结构实验十 哈夫曼编码

【实验内容】 1、假设用于通信的电文仅由8个字母 {a, b, c, d, e, f, g, h} 构成&#xff0c;它们在电文中出现的概率分别为{ 0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10 }&#xff0c;试为这8个字母设计哈夫曼编码。 提示:包含两个过程:&#xff08;1&#xff09;构建…

【iOS】——浅析CALayer

文章目录 一、CALayer介绍二、UIview与CALayer1.区别2.联系 三、CALayer的使用1.初始化方法2.常用属性 四.CALayer坐标系1.position属性和anchorPoint属性2.position和anchorPoint的关系3.position、anchorPoint和frame的关系 五、CALayerDelegate六、CALayer绘图机制1.绘图流程…

利用Jenkins完成Android项目打包

问题和思路 目前存在的问题 打包操作由开发人员完成&#xff0c;这样开发进度容易被打断。 解决问题的思路 将打包操作交测试/产品/开发人员来完成&#xff0c;主要是测试/开发。 按照以上的思路&#xff0c;那么JenkinsGradle的解决方案是比较经济的&#xff0c;实现起来…

鸿蒙内核源码分析(互斥锁篇) | 互斥锁比自旋锁丰满多了

内核中哪些地方会用到互斥锁?看图: 图中是内核有关模块对互斥锁初始化,有文件,有内存,用消息队列等等,使用面非常的广.其实在给内核源码加注的过程中,会看到大量的自旋锁和互斥锁,它们的存在有序的保证了内核和应用程序的正常运行.是非常基础和重要的功能. 概述 自旋锁 和…

5.7 线程

进程&#xff1a;解耦稳定&#xff0c;内容之间是不相关的&#xff0c;通信不便利&#xff0c;理论上进程的软硬件的切换时间以及创建开销非常大。--------》资源共享线程实现 线程的问题&#xff1a;本质就是不解耦&#xff0c;一个出问题别的就很有可能出问题&#xff0c;同…

Scanner中next()、nextInt()、nextLine()、hasNext()、hasNextInt()的使用方法及注意事项

目录 1、next()、nextInt()、nextLine()的使用方法及区分 2、循环时如何使用hasNext方法 3、用hasNextInt()作为判断下一个输入是否为数字需要配合next()方法使用 1、next()、nextInt()、nextLine()的使用方法及区分 三者简单定义 next()&#xff1a;此方法遇见第一个有效字符…

使用AIGC生成软件类图表

文章目录 如何使用 AI 生成软件类图表什么是 MermaidMermaid 的图片如何保存&#xff1f;mermaid.liveDraw.io Mermaid可以画什么图&#xff1f;流程图时序图 / 序列图类图状态图甘特图实体关系图 / ER图 如何使用 AI 生成软件类图表 ChatGPT 大语言模型不能直接生成各类图表。…

linux系统下产生Segmentation fault 与 Segmentation fault (core dumped)!!!

最近在学习的过程中&#xff0c;遇到了Segment fault&#xff08;段错误&#xff09;的问题&#xff0c;经过一番查找资料&#xff0c;学到了一些相关知识&#xff0c;这里做一个梳理&#xff0c;以防以后在遇到类似的问题&#xff0c;并且希望能够帮助到大家一丝丝&#xff01…