首页 > 其他分享 >动态数组代码实现

动态数组代码实现

时间:2023-02-25 22:25:36浏览次数:44  
标签:struct 代码 DynamicArray 数组 array 动态 void size

一、动态数组


一般在静态数组定义后,系统就会为其分配对应长度的连续的专有内存空间,可是,我们都知道,不同的运行样例,所需要的数组长度是不一样的,为了所有样例都可以执行,一般我们会将数组长度设置为一个很大的值,比如:我一般都是借助宏定义直接声明1000,这个长度是可以满足我日常所需的。虽然这种方式,满足了一般运行的要求,但是它极大的浪费了内存。

于是我们引出了动态数组的概念,顾名思义,“动态”体现在数组长度可以由用户自己定义上。那么今天来总结一下,动态数组的两种实现方式。

二、单向链表设计思路

1、思路图

2、定义struct dynamicArray结构体

2.1、属性:

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

  • int m_capacity; 数组容量

  • int m_size; 数组大小

struct dynamicArray {

    void **pAddr; //维护真实在堆区创建的数组的指针

    int m_capacity; //数组容量

    int m_size; //数组大小
};

3、 动态数组初始化

//初始化数组
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;
}

3、插入数组

//插入数组
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++;
}

4、遍历数组

//遍历数组
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]);
    }
}

这里myPrint为用户余姚自定义的回调函数

5、删除数组

  • 按位置删除
//删除数组 按位置删除
void removeByPos_DynamicArray(struct dynamicArray *array, int pos) {

    if (array == NULL) {
        return;
    }

    //无效位置删除
    if (pos < 0 || pos > array->m_size - 1) {
        return;
    }
    //数据向前移动一位
    for (int i = 0; i < array->m_size; 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;
        }
    }

myCompare为回调函数,用户自定义比较规则

6、销毁数组

//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)
{
	if (array == NULL)
	{
		return;	
    }
	if (array->pAddr != NULL)
	{
		free(array->pAddr);
		array->pAddr = NULL;
	}
	free(array);
	array = NULL;
}

三、调试

1、回调函数 myPrintPerson

//回调函数
void myPrintPerson(void *data) {
    struct person *p = data;
    printf("姓名:%s,年龄:%d\n", p->name, p->age);
}

2、回调函数 myCompare

//回调函数
int myCompare(void *data1, void *data2) {

    struct person *p1 = data1;
    struct person *p2 = data2;
    p1->name;
    p2->name;

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

3.测试

  • 定义结构体Person
struct person {
    char name[64];
    char age;
};
  • main
int main() {

    //初始化数组
    struct dynamicArray *array = init_DynamicArray(5);

    //准备数据
    struct person p1 = {"亚瑟", 18};
    struct person p2 = {"安琪拉", 12};
    struct person p3 = {"凯", 11};
    struct person p4 = {"孙悟空", 12};
    struct person p5 = {"达摩", 111};
    struct person p6 = {"牛魔", 123};

    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, 0);
    forEach_DynamicArray(array, myPrintPerson);
    printf("删除数据后:容量:%d 大小:%d\n", array->m_capacity, array->m_size);


    struct person p = {"达摩", 111};
    removeByValue_DynamicArray(array, &p, myCompare);
    forEach_DynamicArray(array, myPrintPerson);
    printf("删除数据后:容量:%d 大小:%d\n", array->m_capacity, array->m_size);

    return 0;
}

标签:struct,代码,DynamicArray,数组,array,动态,void,size
From: https://www.cnblogs.com/zggb/p/17155570.html

相关文章

  • 二维数组的声明及其作为函数参数的方式
    ◆概要本文以3行2列的二维数组为例,介绍了如何声明自动存储、静态存储和动态存储的二维数组,及其如何将它们作为函数参数进行传递的方式。◆实现处理自动存储或静态......
  • 代码随想录算法训练营Day24 回溯算法|216.组合总和III 17.电话号码的字母组合
    代码随想录算法训练营216.组合总和III题目链接:216.组合总和III找出所有相加之和为 n的 k 个数的组合。组合中只允许含有1- 9的正整数,并且每种组合中不存在重复......
  • github创建代码储存库,上传代码
    Github说明--如何在Github里面上传自己的代码-yesyes1-博客园(cnblogs.com)我详细看了lzj同学的这篇博客,简单介绍一下,如何上传代码存储到代码库。1.点击头像傍边的......
  • 动态规划DP
    前言:因为在练习算法题时遇到了经典的背包问题,而解决这个问题的最优方法是动态规划为了更多的了解动态规划,结合网上资料和个人理解系统地整理了一份资料可能对于部分人......
  • 数组和指针
    一维数组和指针先回忆一下,数组是由一系列类型相同的元素组成。如:charch[4];/*4个字符的数组*/intin[4];/*4个整数的数组*/floatfl[4];/*4个浮点数的数......
  • Java中的代码块
    Java中的代码块我们在做笔试题的时候经常会遇到考察类中代码块运行顺序的题,所以我现在把它总结一下。在Java中,代码块(Block)是用一对大括号括起来的一段代码,它可以包含多条......
  • 后缀数组做题笔记
    后缀数组笔记这里挂一个学弟学习笔记的链接:Link,大部分内容都学习自这里。按道理这篇文章会持续更新1.Preface​ 首先有几个概念需要明确。本文中所有字符串下标从\(1......
  • 关于低代码和无代码---喧嚣背后的致命问题
    前言2021年的时候,刮起了一阵”低代码”和”无代码”的风,结果猪没见吹起来,风却早早停了。在我的职业生涯中遇到了很多的低代码的构想和实现,通常他们的想法非常朴素:写代码......
  • web前端开发第202页习题3代码
    排序参考1<!DOCTYPEhtml>2<htmllang="en">34<head>5<metacharset="UTF-8">6<metahttp-equiv="X-UA-Compatible"content="IE=edge">7......
  • 二维字符数组
    当有多个字符串时,可以使用二维字符数组例如:chararr[3][128]={"hello","world","hehehe"};二维字符数组的遍历 ......