嵌入式学习-02_数据结构和算法 (数组)

本文详细介绍了C语言中数组的基础知识、优缺点,以及动态数组的实现原理,包括内存分配函数malloc、realloc和free的运用。通过示例展示了动态数组的初始化、插入、删除和内存管理过程。
摘要由CSDN通过智能技术生成

嵌入式学习-02_数据结构和算法 (数组)

1 线性结构之数组

1.1 基础知识

C 语言中,数组是具有相同类型的数据元素的集合。在所有的数据结构中,数组算是最常见、最简单的一种数据结构。

C 语言中,数组的长度一旦确定就不可以再变了。

1.2 数组优缺点

优 点

Ø 查找容易(通过下标),时间复杂度为O(1)。不需要额外申请或删除空间。

Ø 使用下标位置索引(index)十分高效的访问任意元素,修改快

在这里插入图片描述

缺 点

Ø 插入、删除元素难,效率低。(需要移动大量元素以使元素空间连续)。

Ø 插入操作平均需要移动n/2个元素。

Ø 删除操作平均需要移动(n-1)/2个元素。

在这里插入图片描述

Ø 扩展相对繁琐。一方面需要确保能提供更大区域的连续内存空间,另一方面需要将原有数据复制到新的顺序表中。

1.4 实现原理

可变长的动态数组是一种数据结构,它允许在运行时根据需要动态地调整数组的大小,而不需要提前指定固定的大小。这种动态数组通常被称为动态数组、动态分配数组、动态增长数组或动态内存数组。int arr[10];

C语言中是通过使用指针和内存分配函数来实现动态数组,常见的内存分配函数是malloc、realloc和free。下面是一些相关的概念和操作:

(1)分配内存(malloc): 在C语言中,可以使用malloc函数来分配一块指定大小的内存。例如,int *arr = (int *)malloc(n * sizeof(int)); 将分配能够存储n个整数的内存空间。

(2)重新分配内存(realloc): 如果需要改变动态数组的大小,可以使用realloc函数来重新分配内存。这允许你在保留原有数据的情况下扩展或缩小数组的大小。

(3)释放内存(free): 当不再需要动态数组时,应使用free函数释放之前分配的内存,以避免内存泄露。à 内存溢出

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//定义元素类型,类型别名
typedef int element_t;

//定义结构体 表示动态数组类型
typedef struct 
{
    element_t *data ;  //指向存放元素的内存区域
    size_t size;       //表示已经存在的元素个数
    size_t capacity;   //最大容量
} DynamicArray;


 //
 /**
  * @brief 初始化动态数组
  * @param DynamicArray *array
  * @param size_t initialCapacity
 */
void initDynamicArray(DynamicArray *array, size_t initialCapacity)
{
    //给数组分配空间
    array -> data = (element_t *) malloc(sizeof (element_t) * initialCapacity);
    //成员初始化赋值
    array -> capacity = initialCapacity;
    array -> size = 0;
}


/**
 * @brief 释放动态数组内存
 * @param DynamicArray *array 动态数组
*/
void destroyDynamicArray(DynamicArray *array)
{
    free(array -> data);
    //重置内存的值
    array -> data =NULL;
    array -> capacity = 0;
    array -> size = 0;
}


/**
 * @brief 调整动态数组内存大小
 * @param size_t newCapacity  动态数组
 * @param DynamicArray *array  新的容量
*/
void resizeDynamicArray(DynamicArray *array, size_t newCapacity)
{
    //重新分配内存大小
    array -> data = (element_t *)realloc(array -> data, sizeof(element_t) * newCapacity);
    array -> capacity = newCapacity;
}

/**
 * @brief 获取动态数组长度(元素个数)
 * @param const DynamicArray *array   const不能修改array
*/
size_t getLength(const DynamicArray *array)
{
    return array -> size;
}

/**
 * @brief 在指定位置插入新元素
 * @param DynamicArray *array 动态数组
 * @param size_t index        位置(下标)
 * @param element_t element   新元素
*/
void insertAt(DynamicArray *array, size_t index, element_t element)
{
    //如果下标不在合理范围内,退出
    if (index > array -> size)
    {
        return;
    }

    // 如果内存空间不够,扩展内存
    if (array -> size == array -> capacity)
    {
        // 调用函数,重新分配内存空间
        resizeDynamicArray(array, array -> capacity * 2);
    }

    //循环遍历, 从插入位置开始,将前面的值赋给后面的元素
    for (size_t i = array -> size; i > index; i--)
    {
        array -> data[i] = array -> data[i-1];
    }

    //添加新元素
    array -> data[index] = element;

    //元素个数自增加
    array -> size ++;
    
}


/**
 * @brief 在末尾插入新元素
 * @param DynamicArray *array
 * @param element_t element
*/
void insertEnd(DynamicArray *array, element_t element)
{
    //调用插入函数
    insertAt(array, array -> size, element);
}


/**
 * @brief 删除指定位置的元素并返回被删除的元素
 * @param DynamicArray *array
 * @param size_t index
 * @param element_t *deleted_element  用于保存删除元素
 * @return boo1 是否删除成功 1 成功 ; 0 失败
*/
element_t deleteAt(DynamicArray *array, size_t index, element_t *deleted_element)
{
    //如果果下标不在合理范围内
    if (index >= array -> size)
    {
        return 0;
    }
    
    // 把被删除元素记录
    *deleted_element = array -> data[index];

    // 循环将后面元素赋值给前面元素
    for (size_t i = index; i < array -> size - 1; i++)
    {
        array -> data[i] = array -> data[i + 1];
    }
    
    // 数组长度自减
    array -> size --;

    return 1;
}


//
/**
 * @brief 删除末尾的元素并返回被删除的元素
 * @param DynamicArray *array
 * @param element_t *deleted_element  用于保存删除元素
 * @return bool 是否删除成功 1 成功 ; 0 失败
*/
element_t deleteEnd(DynamicArray *array, element_t *deleted_element)
{
    return deleteAt(array, array -> size - 1, deleted_element);
}


/**
 * @brief 遍历所有的元素
 * @param DynamicArray *array
*/
void print(DynamicArray *array)
{
    for (size_t i = 0; i < array -> size; i++)
    {
        printf("%d ",array -> data[i]);
    }
    
}


int main(){
// 定义动态数组
    DynamicArray da;

    // 初始化动态数组
    initDynamicArray(&da, 2);

    // 在末尾追加元素
    insertEnd(&da, 100);
    insertEnd(&da, 200);
    insertEnd(&da, 300);
    insertEnd(&da, 400);

    // 插入新元素
    insertAt(&da, 1, 250);

    printf("数组中的元素:");
    print(&da);
    printf("\n数组长度:%zu \n", getLength(&da));
    printf("\n\n");

    // 删除
    element_t num;
    deleteAt(&da, 1, &num);
    printf("被删除的元素:%d \n", num);

    deleteEnd(&da, &num);
    printf("被删除的元素:%d \n", num);


    printf("数组中的元素:");
    print(&da);
    printf("\n数组长度:%zu \n", getLength(&da));

    // 释放内存
    destroyDynamicArray(&da);



    return 0;
}

printf(“被删除的元素:%d \n”, num);

deleteEnd(&da, &num);
printf("被删除的元素:%d \n", num);


printf("数组中的元素:");
print(&da);
printf("\n数组长度:%zu \n", getLength(&da));

// 释放内存
destroyDynamicArray(&da);



return 0;

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路x飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值