数据结构之动态数组

简述

    动态数组类似普通数组,内存空间都是连续的,可根据下标访问元素,普通数组定义时就会分配好空间,内存大小固定不变了,无法扩容,数据容易越界,但动态内存的大小会随着数据的增长而扩容。

    动态数组看似内存空间在原来的基础上增长了,其实它只是申请了一块更大的内存,并把旧内存空间的数据拷贝到新申请的内存空间中,再把旧的空间释放掉,就这样一旦 发现当前内存快满,就会申请一块新的,同理,当数据变少时,就会申请一块小的内存空间,周而复始,就是动态内存,


实现

DynaminArray.h

#ifndef DYNAMIC_ARRAY
#define DYNAMIC_ARRAY

#include<stdlib.h>
#include<stdio.h>

typedef struct _DynaminArray
{
	void **data;
	int capacity;
	int size;
}DynaminArray;

//初始化动态数组
DynaminArray* init_DynaminArray();
//在指定位置插入(动态增长)
void insert_DynaminArray(DynaminArray* arr, int pos, void *data);
//头插
void front_DynaminArray(DynaminArray* arr, void *data);
//尾插
void back_DynaminArray(DynaminArray* arr, void *data);
//遍历
void foreach_DynaminArray(DynaminArray* arr, void(*print)(void*));
//指定位置删除
void remove_DynaminArray(DynaminArray* arr, int pos);
//根据值来删除
void num_remove_DynaminArray(DynaminArray* arr, void *data, int(*compare)(void*, void*));
//销毁数组
void Destroy_DynamicArray(DynaminArray* arr);
//返回数据大小
int Size_DynamicArray(DynaminArray* arr);
//返回内存空间大小
int Capacity_DynamicArray(DynaminArray *arr);
//根据数组位置查找数据
void* Value_DynamicArray(DynaminArray *arr, int pos);


#endif


DynaminArray.c

#include"DynaminArray.h"


//初始化动态数组
DynaminArray* init_DynaminArray()
{
	DynaminArray* arr = (DynaminArray*)malloc(sizeof(DynaminArray));
	if (NULL == arr)
	{
		printf("error: func init_DynaminArray  文件%s第%d行", __FILE__, __LINE__);
		return NULL;
	}
	arr->capacity = 10;
	arr->size = 0;
	arr->data = (void **)malloc(sizeof(void*)* arr->capacity);
	for (int i = 0; i < arr->capacity; i++)
	{
		arr->data[i] = NULL;
	}

	return arr;
}
//指定位置插入(动态增长)
void insert_DynaminArray(DynaminArray* arr, int pos, void *data)
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	//如果pos < 0;或者 pos > arr->size,调整pos到尾部 pos = size
	if (pos < 0 || pos > arr->size)
	{
		pos = arr->size;
	}
	
	if (arr->size == arr->capacity)
	{
		//增长空间
		int newcapacity = arr->capacity * 2;
		//申请更大内存空间
		void **newspace = malloc(sizeof(void *)* newcapacity);
		//拷贝数据
		for (int i = 0; i < arr->size; i++)
		{
			newspace[i] = arr->data[i];
		}
		//释放旧内存空间
		free(arr->data);
		arr->data = newspace;
		arr->capacity = newcapacity;
	}
	//移动元素
	if (pos >= 0 && pos < arr->size)
	{
		for (int i = arr->size - 1; i >= pos; i--)
		{
			arr->data[i + 1] = arr->data[i];
		}
	}
	//将新元素添加到数组中
	arr->data[pos] = data;
	arr->size++;
	arr = NULL;
	data = NULL;

	return;
}
//头插
void front_DynaminArray(DynaminArray* arr, void *data)
{
	insert_DynaminArray(arr, 0, data);
}
//尾插
void back_DynaminArray(DynaminArray* arr, void *data)
{
	insert_DynaminArray(arr, arr->size, data);
}
//遍历
void foreach_DynaminArray(DynaminArray* arr, void(*print)(void *))
{
	if (NULL == arr)
	{
		return;
	}
	if (NULL == print)
	{
		return;
	}
	for (int i = 0; i < arr->size; i++)
	{
		print(arr->data[i]);
	}
}
//指定位置删除
void remove_DynaminArray(DynaminArray* arr, int pos)
{
	if (NULL == arr)
	{
		return;
	}
	if (pos < 0 || pos > arr->size - 1)
	{
		return;
	}
	if (arr->size == 0)
	{
		return;
	}
	for (int i = 0; i < arr->size; i++)
	{
		arr->data[i] = arr->data[i + 1];
	}
	arr->size--;
}
//根据值来删除
void num_remove_DynaminArray(DynaminArray* arr, void *data, int(*compare)(void*, void*))
{
	if (NULL == arr)
	{
		return ;
	}
	if (NULL == data)
	{
		return ;
	}
	if (NULL == compare)
	{
		return ;
	}
	if (arr->size == 0)
	{
		return ;
	}
	for (int i = 0; i < arr->size; i++)
	{
		if (compare(arr->data, data))
		{
			remove_DynaminArray(arr, i);
		}
	}
	return;
}
//销毁数组
void Destroy_DynamicArray(DynaminArray* arr)
{
	if (NULL == arr)
	{
		return;
	}
	if (arr->data != NULL)
	{
		free(arr->data);
		arr->data = NULL;
	}
	arr->capacity = 0;
	arr->size = 0;
	free(arr);
	arr = NULL;
}
//返回数据大小
int Size_DynamicArray(DynaminArray* arr)
{
	return arr->size;
}
//返回内存空间大小
int Capacity_DynamicArray(DynaminArray *arr)
{
	return arr->capacity;
}
//根据数组位置查找数据
void* Value_DynamicArray(DynaminArray *arr, int pos)
{
	if (NULL == arr)
	{
		return NULL;
	}
	if (pos < 0 || pos >= arr->size)
	{
		return NULL;
	}
	return arr->data[pos];
}

测试代码
main.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"DynaminArray.h"
struct Person
{
	char name[64];
	int age;
};
 void print(void* data)
{
	 struct Person *p = (struct Person *)data;
	 printf("name:%s age:%d\n", p->name, p->age);
}
 int compare(void *d1, void *d2){
	 struct Person *p1 = (struct Person *)d1;
	 struct Person *p2 = (struct Person *)d2;

	 return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
 }
int main(){

	struct Person p1 = { "aaa", 10 };
	struct Person p2 = { "bbb", 20 };
	struct Person p3 = { "ccc", 30 };
	struct Person p4 = { "ddd", 40 };
	struct Person p5 = { "eee", 50 };
	struct Person p6 = { "fff", 60 };
	struct Person p7 = { "ggg", 70 };
	struct Person p8 = { "hhh", 80 };
	struct Person p9 = { "kkk", 90 };
	struct Person p10 = { "ppp", 100 };
	struct Person p11 = { "qqq", 110 };
	struct Person p12 = { "zzz", 120 };
	初始化动态数组
	DynaminArray* arr = init_DynaminArray();
	//将数据插入到数组中
	insert_DynaminArray(arr, 100, &p1);
	insert_DynaminArray(arr, 100, &p2);
	insert_DynaminArray(arr, 100, &p3);
	insert_DynaminArray(arr, 100, &p4);
	insert_DynaminArray(arr, 100, &p5);
	insert_DynaminArray(arr, 100, &p6);
	insert_DynaminArray(arr, 100, &p7); 
	insert_DynaminArray(arr, 100, &p8);
	foreach_DynaminArray(arr, print);

	printf("******************************\n");
	front_DynaminArray(arr, &p9);
	front_DynaminArray(arr, &p10);
	foreach_DynaminArray(arr, print);

	printf("******************************\n");
	back_DynaminArray(arr, &p11);
	back_DynaminArray(arr, &p12);
	foreach_DynaminArray(arr, print);

	printf("******************************\n");

	int len = Size_DynamicArray(arr);
	int len1 = Capacity_DynamicArray(arr);
	struct Person *str = Value_DynamicArray(arr, 8);
	printf("%d\t%d\n%s\t%d\n", len, len1, str->name, str->age);
	
	Destroy_DynamicArray(arr);

	system("pause");
	return EXIT_SUCCESS;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值