简述
动态数组类似普通数组,内存空间都是连续的,可根据下标访问元素,普通数组定义时就会分配好空间,内存大小固定不变了,无法扩容,数据容易越界,但动态内存的大小会随着数据的增长而扩容。
动态数组看似内存空间在原来的基础上增长了,其实它只是申请了一块更大的内存,并把旧内存空间的数据拷贝到新申请的内存空间中,再把旧的空间释放掉,就这样一旦 发现当前内存快满,就会申请一块新的,同理,当数据变少时,就会申请一块小的内存空间,周而复始,就是动态内存,
实现
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;
}