1.2 线性结构之数组
1.2.1 基础知识
1.2.2 数组优缺点
优点:易查找,时间复杂度为O(1),不需要额外申请或删除空间,使用下标位置索引index十分高校的访问任意元素。
缺点:插入,删除难度高,效率低,需要移动大量元素以使元素空间连续
插入操作平均需要移动n/2个元素。
删除操作平均需要移动(n-1)/2个元素
空间扩展相对繁琐:一方面需要确保能提供更大区域的连续内存空间,一方面需要将原有数据复制到新的顺序中。
1.2.3 功能定义
//初始化动态数组 |
---|
void initDynamicArray(DynamicArray *array, size_t initialCapacity) |
//释放动态数组内存 |
void destroyDynamicArray(DynamicArray *array) |
//调整动态数组内存大小 |
void resizeDynamicArray(DynamicArray *array, size_t newCapacity) |
//获取动态数组长度(元素个数) |
size_t getLength(const DynamicArray *array) |
//在指定位置插入新元素 |
void insertAt(DynamicArray *array, size_t index, int element) |
//在末尾插入新元素 |
void insertEnd(DynamicArray *array, int element) |
//删除指定位置的元素并返回被删除的元素 |
int deleteAt(DynamicArray *array, size_t index) |
//删除末尾的元素并返回被删除的元素 |
int deleteEnd(DynamicArray *array) |
//遍历所有的元素 |
void print(DynamicArray *array) |
1.2.4 实现原理
C语言中是通过使用指针和内存分配函数来实现动态数组,常见的内存分配函数是malloc、realloc和free。下面是一些相关的概念和操作:
(1)分配内存(malloc): 在C语言中,可以使用malloc函数来分配一块指定大小的内存。例如,int *arr = (int *)malloc(n * sizeof(int)); 将分配能够存储n个整数的内存空间。
(2)重新分配内存(realloc): 如果需要改变动态数组的大小,可以使用realloc函数来重新分配内存。这允许你在保留原有数据的情况下扩展或缩小数组的大小。
(3)释放内存(free): 当不再需要动态数组时,应使用free函数释放之前分配的内存,以避免内存泄露。–>内存溢出
1.2.5代码实现
#include <stdio.h>
#include<stdlib.h>
/**
* 声明动态数组并提供相关的函数
*/
// 声明动态数组的结构体
typedef struct Array
{
// 声明存储数据的数组
int *data;
// 记录数组的容量
size_t capacity;
// 记录数组中存储的数据的长度
size_t size;
} DynamicArray;
// 初始化动态数组
void initDynamicArray(DynamicArray *array, size_t initialCapacity)
{
// 动态创建数组的方式
array->data = (int *)malloc(initialCapacity * sizeof(int));
// 初始化capacity成员
array->capacity = initialCapacity;
// 初始化size成员
array->size = 0;
printf("初始化完成\n");
}
// 释放动态数组内存
void destroyDynamicArray(DynamicArray *array)
{
// 释放数组空间
free(array->data);
// 修改capacity,size默认值
array->capacity = 0;
array->size = 0;
}
// 调整动态数组内存大小
void resizeDynamicArray(DynamicArray *array, size_t newCapacity)
{
// 修改data数组,进行扩容
array->data = (int *)realloc(array->data, newCapacity * sizeof(int));
// 修改capacity
array->capacity = newCapacity;
printf("扩容\n");
}
// 获取动态数组长度(元素个数)
size_t getLength(const DynamicArray *array)
{
return array->size;
}
// 在指定位置插入新元素
void insertAt(DynamicArray *array, size_t index, int element)
{
if (index < 0 || index > array->size)
{
printf("index不合法,插入失败\n");
return; // 表示插入失败
}
if (array->size == array->capacity)
{
// 数据满了进行扩容
resizeDynamicArray(array, array->capacity << 1);
}
for (int i = array->size; i > index; i--)
{
array->data[i] = array->data[i - 1];
}
// 修改index位置的数据
array->data[index] = element;
// 修改长度
array->size++;
}
// 在末尾插入新元素
void insertEnd(DynamicArray *array, int element)
{
insertAt(array, array->size, element);
}
// 删除指定位置的元素并返回被删除的元素
int deleteAt(DynamicArray *array, size_t index)
{
if (index < 0 || index >= array->size)
{
printf("数据不合法!\n");
return -1;
}
// 获取要删除位置元素的数据
int deleteData = array->data[index];
for (int i = index; i < array->size - 1; i++)
{
array->data[i] = array->data[i + 1];
}
array->size--;
return deleteData;
}
// 删除末尾的元素并返回被删除的元素
int deleteEnd(DynamicArray *array)
{
deleteAt(array, array->size - 1);
}
// 遍历所有的元素
void print(DynamicArray *array)
{
for (int i = 0; i < array->size; i++)
{
printf("%d\n", array->data[i]);
}
printf("\n");
}
int main()
{
DynamicArray array;
initDynamicArray(&array, 10);
insertAt(&array, 0, 10);
insertAt(&array, 0, 20);
insertAt(&array, 0, 21);
print(&array);
// resizeDynamicArray();
return 0;
}