数据结构---动态数组

 一、数据结构基本理论

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

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

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

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

二、动态数组实现

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.hqwc.cn/news/675470.html

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

相关文章

Elasticsearch:使用 MongoDB connector 同步数据到 Elasticsearch

MongoDB 是一个基于分布式文件存储的数据库。由 C 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。Elasticsearch 是一个高效强…

LTE的EARFCN和band之间的对应关系

一、通过EARFCN查询对应band 工作中经常遇到只知道EARFCN而需要计算band的情况&#xff0c;因此查了相关协议&#xff0c;找到了他们之间的对应关系&#xff0c;可以直接查表&#xff0c;非常方便。 具体见&#xff1a; 3GPP TS 36.101 5.7.3 Carrier frequency and EAR…

java+jsp+Oracle+Tomcat 记账管理系统论文(完整版)

⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️⬇️ ➡️点击免费下载全套资料:源码、数据库、部署教程、论文、答辩ppt一条龙服务 ➡️有部署问题可私信联系 ⬆️⬆️⬆️​​​​​​​⬆️…

【busybox记录】【shell指令】uniq

目录 内容来源&#xff1a; 【GUN】【uniq】指令介绍 【busybox】【uniq】指令介绍 【linux】【uniq】指令介绍 使用示例&#xff1a; 去除重复行 - 默认输出 去除重复行 - 跳过第n段&#xff08;空格隔开&#xff09;&#xff0c;比较n1以后的内容&#xff0c;去重 去…

2024-05-07 商业分析-赚钱之前怎么预估风险-记录

摘要: 2024-05-07 商业分析-赚钱之前怎么预估风险-记录 赚钱之前怎么预估风险 好&#xff0c;大家好&#xff0c;今天我们来讲的是叫什么赚钱之前怎么评估风险啊&#xff0c;这个问题啊提的很好啊&#xff0c;我们待会儿来讲啊。呃&#xff0c;首先呢今天这个主题呢来自于昨天…

常用算法汇总

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;算法思维逻辑&#x1f43e; 文章目录 1.判断闰年2.计算从某天到某天的天数3.二分4. 前缀和5.差分6.图论6.1dfs6.2走迷宫 7.最短路7.1dijkstra7.2foly 8.并查集9.数论9.1gcd lcm9.2判断素数(质数)9.3分解质因…

GNU Radio FFT模块结合stream to vector应用及Rotator频偏模块使用

文章目录 前言一、FFT 模块应用1、stream to vector 介绍2、创建 grc 图测试3、运行结果 二、频偏模块1、Rotator 简介2、创建 grc 图测试3、运行结果 前言 写个博客记录一下自己的蠢劲儿&#xff0c;之前我想用 FFT 模块做一些信号分析的东西&#xff0c;官方的 FFT 模块必须…

论文复现丨多车场带货物权重车辆路径问题:改进邻域搜索算法

引言 本系列文章是路径优化问题学习过程中一个完整的学习路线。问题从简单的单车场容量约束CVRP问题到多车场容量约束MDCVRP问题&#xff0c;再到多车场容量时间窗口复杂约束MDCVRPTW问题&#xff0c;复杂度是逐渐提升的。 如果大家想学习某一个算法&#xff0c;建议从最简单…

快速了解OV证书和DV证书的区别及使用场景

OV&#xff08;Organization Validation&#xff0c;组织验证&#xff09;证书和DV&#xff08;Domain Validation&#xff0c;域名验证&#xff09;证书都是SSL/TLS证书&#xff0c;用于保护网站数据传输的安全性和提供身份验证&#xff0c;但两者在验证深度、信任级别、提供的…

分布式锁-快速入门

文章目录 前言一、基础概念1.1 什么是锁1.2 什么是分布式锁1.3 锁和事务的区别二、分布式锁基础理论2.1 为什么要使用分布式锁2.2 分布式锁特性2.3 分布式锁的实现方式总结前言 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题…

【软测学习笔记】Python入门Day02

&#x1f31f;博主主页&#xff1a;我是一只海绵派大星 &#x1f4da;专栏分类&#xff1a;软件测试笔记 &#x1f4da;参考教程&#xff1a;黑马教程❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ python安装 1、进入Python的官方下载页面&#xff1a; Download Python | Py…

c#教程——索引器

前言&#xff1a; 索引器&#xff08;Indexer&#xff09;可以像操作数组一样来访问对象的元素。它允许你使用索引来访问对象中的元素&#xff0c;就像使用数组索引一样。在C#中&#xff0c;索引器的定义方式类似于属性&#xff0c;但具有类似数组的访问方式。 索引器&#x…