嵌入式学习-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;
}