数据结构---动态数组

news2024/11/24 22:48:56

 一、数据结构基本理论

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

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

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

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

二、动态数组实现

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.coloradmin.cn/o/1649151.html

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

相关文章

中国居民消费新特征:中枢回落,即时满足,去地产化

随着收入预期和财富效应的转变&#xff0c;居民更倾向于通过短期集中式的消费来获得即时满足的快乐&#xff0c;服务消费表现出了更强的韧性。服务消费强于商品消费、消费去地产化、汽车挑大梁的特征延续。 特征一&#xff1a;消费倾向高于2020-22年&#xff0c;低于2017-19年…

zabbix监控方式(zabbix-trapper)

中文&#xff1a;zabbix采集器&#xff0c;即zabbix sender 。 Zabbix-Trapper 监控方式可以一次批量发送数据给Zabbix Server&#xff0c;与主动模式不同&#xff0c;Zabbix-Trapper 可以让用户控制数据的发送&#xff0c;而不用Zabbix-Agent进程控制&#xff0c;这意味着可以…

数据挖掘算法原理与实践:决策树

第2关&#xff1a;决策树算法原理 任务描述 本关任务&#xff1a;根据本关所学知识&#xff0c;完成 calcInfoGain 函数。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 信息熵&#xff1b;条件熵&#xff1b;信息增益。 信息熵 信息是个很抽象的概念。…

2.4V转3.8V/3.9V供电升压方案:为水表提供稳定电力

随着科技的不断发展&#xff0c;水表等智能设备在我们的生活中扮演着越来越重要的角色。为了让水表得以正常工作&#xff0c;稳定的电力供应是至关重要的。在这篇文章中&#xff0c;我们将探讨一种2.4V转3.8V/3.9V供电方案&#xff0c;以确保为水表提供稳定的电力。 为了实现2…

算法提高之玉米田

算法提高之玉米田 核心思想&#xff1a;状态压缩dp 将图存入g数组 存的时候01交换一下方便后面判断即g数组中0为可以放的地方 state中1为放的地方 这样只要state为1 g为0就可以判断不合法 #include <iostream>#include <cstring>#include <algorithm>#includ…

访问网络附加存储:nfs

文章目录 访问网络附加存储一、网络附加存储1.1、存储类型1.3、通过NFS挂载NAS1.4、NFS挂载过程服务端客户端 二、实验&#xff1a;搭建NFS服务端及挂载到nfs客户端服务端客户端测试命令合集服务端客户端 访问网络附加存储 一、网络附加存储 1.1、存储类型 DAS&#xff1a;Di…

照片太大上传不了怎么缩小?教你几招压缩图片

在日常的工作和学习中&#xff0c;我们经常要用到一些图片文件&#xff0c;储存的图片多了之后&#xff0c;会对我们的电脑或者手机有影响&#xff0c;需要我们使用图片处理工具来压缩图片大小&#xff0c;那么有没有比较简单的图片压缩的方法呢&#xff1f;试试今天分享的几个…

c++ cpp 在类中执行线程 进行恒定计算

在编程中&#xff0c;顺序执行是常见的模式&#xff0c;但是对cpu的利用率不是很高&#xff0c;采用线程池&#xff0c;又太麻烦了&#xff0c;原因是还得不断地把任务拆分&#xff0c;扫描返回值。 如果 初始化n个类的时候&#xff0c;传递数据自身即可异步计算&#xff0c;那…

产品专访|“产品”远程运维系统与“设备”远程运维系统的区别?

在日益复杂的工业制造环境下&#xff0c;远程运维已经成为生产制造企业不可或缺的一部分。在这个大背景下&#xff0c;产品远程运维系统和设备远程运维系统的需求越来越多&#xff0c;各自发挥着独特的作用。然而&#xff0c;尽管它们都涉及到远程运维的概念&#xff0c;但在实…

好消息|5月6日起换发补发出入境证件可“全程网办”

国家移民管理局从2024年5月6日起&#xff0c;实施若干便民利企出入境管理的六项政策措施&#xff0c;包括在北京等20个城市试点实行换发补发出入境证件的“全程网办”&#xff0c;该举措对于访问学者、博士后研究人员及联合培养博士都是利好消息。故知识人网小编转载发布。 为更…

【影片欣赏】【指环王】【魔戒:护戒使者 The Lord of the Rings: The Fellowship of the Ring】

2001年发行&#xff0c;Extended DVD Edition Part One 1. Prologue: One Ring to Rule Them All… 2. Concerning Hobbits 3. The Shire 4. Very Old Friends 5. A Long-expected Party 6. Farewell Dear Bilbo 7. Keep It Secret, Keep It Safe 8. The Account of Isildur 9…

在ubuntu虚拟机中手动安装VMware Tools(VMware Workstation 17 player)

可参考官方文档&#xff1a;在 Linux 虚拟机中手动安装 VMware Tools 以下列出我在安装过程中遇见的问题&#xff1a; 1、“安装VMware Tools”选项为灰&#xff0c;无法选中 原因是VMware Tools的安装包镜像在Player的安装目录下&#xff0c;需要在虚拟机启动的时候加载这个…

el-collapse中title两端对齐

el-collapse中title两端对齐 最后效果 <el-collapse><el-collapse-item title"" name"1"><template slot"title"><div class"tablis"><div>04-02-18</div><div>XXXXXXX</div><di…

Elsevier旗下双1区TOP刊,8.8分影响因子加上超低自引率,各指标领跑计算机类SCI

【SciencePub学术】 今天小编给大家带来了一本计算机类的高分优刊解读&#xff0c;隶属于Elsevier出版社&#xff0c;JCR1区&#xff0c;中科院1区TOP&#xff0c;影响因子高达8.7&#xff0c;领域相符的学者可考虑&#xff01; APPLIED SOFT COMPUTING 1 期刊概况 【期刊简…

yolo-world:”目标检测届大模型“

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…

酷得智能电子方案 早教学习机

早教学习机是用户友好的&#xff0c;易于操作&#xff0c;同时要确保内容的科学性和适宜性&#xff0c;以促进儿童的健康成长和智力发展。 通常包括以下几个方面&#xff1a; 1.年龄分级内容&#xff1a;软件会根据儿童的不同年龄段提供相应的教育内容&#xff0c;从新生儿到…

设置多用户远程登录windows server服务器

##设置多用户远程登录windows server服务器 ###1、远程登录windows server 2016 运行—>mstsc—>远程IP地址—>用户和密码 2、远程windows服务器设置多用户策略 运行—>gpedit.msc->计算机配置—管理模板—windows组件—远程桌面服务—远程桌面会话主机----连…

庐山西海服务区:从高速服务区到旅游热点的华丽转身

五一假期期间&#xff0c;庐山西海服务区以其独特的魅力吸引了众多游客的目光。曾经只是一个供汽车加油和休息的普通服务区&#xff0c;如今却焕发出了绚丽的光彩&#xff0c;成为了周边地区备受瞩目的旅游热点。庐山西海服务区的转型&#xff0c;不仅为游客带来了丰富多样的娱…

夏天旅行,就认准这五款随身WiFi!准没错!2024随身wifi靠谱品牌推荐,高性价比高口碑随身wifi推荐

过了五一&#xff0c;气温逐渐上升&#xff0c;又到了最适合旅行的季节。这个时候一款趁手的随身WiFi当然是必不可少的&#xff01;不但能解决出行时信号差的烦恼&#xff0c;还可以解决流量不够用的问题。那么&#xff0c;都有哪些随身WiFi在夏季出行时最值得选择呢&#xff1…

【蓝桥杯备赛国赛】5-5

文章目录 求阶乘双子数 求阶乘 求阶乘 分析k的范围&#xff0c;10的18次方。这个数字很大 想要末尾有0的存在必须要2和5&#xff0c;但是通过分析2的数目应该是远远多于5的&#xff0c;所以只要5的数目够多即可。所以for循环的层次也是10的九次方以上&#xff0c;必然会超时&…