数据结构与算法之动态数组
动态数组是一种可变大小的数组,它可以随着数据的增加和删除而改变其大小。其原理是使用了空间预分配机制和动态扩展机制。
在空间预分配机制中,动态数组会开辟一段较大的连续内存空间,用于存储数据,并在需要时动态地调整数据存储空间的大小。一般情况下,动态数组会预分配比当前需要的空间更多的内存空间,这样避免了频繁的内存分配和释放操作,从而提高了性能。
在动态扩展机制中,当动态数组中的元素数量超过了预分配的空间大小,动态数组会自动进行扩展操作,以容纳更多的元素。具体的扩展操作会根据不同的实现方式而有所不同,有的实现会将动态数组的内部空间扩大一倍,有的实现会在一定规则下进行扩展。使用动态扩展机制,能够充分利用内存空间,避免数据溢出,从而提高了动态数组的容量和性能。
总的来说,动态数组的原理就是在预分配一定的存储空间的基础上,通过动态扩展机制进行动态调整,以适应不同大小的数据存储需求。
一、C 动态数组实现及详解
C语言中动态数组的实现通常基于指针和内存动态分配。动态数组的好处在于可以根据实际需要动态的调整数组长度,节省内存空间。
以下是一种基于指针和内存动态分配的动态数组实现方法:
- 声明动态数组的结构体
typedef struct {
int *array;
int size;
} dyn_array;
- 初始化动态数组
void init_array(dyn_array *da, int size) {
da->size = size;
da->array = (int *)malloc(size * sizeof(int));
if (da->array == NULL) {
printf("Memory allocation error.\n");
exit(1);
}
}
- 访问动态数组元素
int get_element(dyn_array *da, int index) {
if (index >= 0 && index < da->size) {
return *(da->array + index);
} else {
printf("Index out of range.\n");
exit(1);
}
}
void set_element(dyn_array *da, int index, int value) {
if (index >= 0 && index < da->size) {
*(da->array + index) = value;
} else {
printf("Index out of range.\n");
exit(1);
}
}
- 扩展动态数组
void resize_array(dyn_array *da, int new_size) {
da->array = (int *)realloc(da->array, new_size * sizeof(int));
if (da->array == NULL) {
printf("Memory allocation error.\n");
exit(1);
}
da->size = new_size;
}
- 释放动态数组内存
void free_array(dyn_array *da) {
free(da->array);
da->array = NULL;
da->size = 0;
}
具体使用方法可以参考以下示例代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *array;
int size;
} dyn_array;
void init_array(dyn_array *da, int size);
int get_element(dyn_array *da, int index);
void set_element(dyn_array *da, int index, int value);
void resize_array(dyn_array *da, int new_size);
void free_array(dyn_array *da);
int main() {
dyn_array my_array;
int i;
init_array(&my_array, 5);
for (i = 0; i < my_array.size; i++) {
set_element(&my_array, i, i * 2);
}
printf("Array elements:\n");
for (i = 0; i < my_array.size; i++) {
printf("%d ", get_element(&my_array, i));
}
printf("\n");
resize_array(&my_array, 10);
for (i = 5; i < my_array.size; i++) {
set_element(&my_array, i, i * 2);
}
printf("Resized array elements:\n");
for (i = 0; i < my_array.size; i++) {
printf("%d ", get_element(&my_array, i));
}
printf("\n");
free_array(&my_array);
return 0;
}
输出结果:
Array elements:
0 2 4 6 8
Resized array elements:
0 2 4 6 8 10 12 14 16 18
二、C++ 动态数组实现及详解
C++ 动态数组是一种灵活的数据结构,它可以在程序运行时动态地分配内存空间。这种数组的大小可以随着程序的需要而改变。动态数组的实现可以使用 C++ 中的标准模板库(STL)中的容器,比如 vector、deque 等。
下面介绍一种基本的 C++ 动态数组实现方式:
#include <iostream>
using namespace std;
int main() {
int size;
cout << "Enter the size of the array: ";
cin >> size;
int* arr = new int[size];
cout << "Enter " << size << " integers:" << endl;
for (int i = 0; i < size; i++) {
cin >> arr[i];
}
cout << "The array is: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
delete[] arr;
return 0;
}
以上代码使用了动态分配内存空间的方式创建了一个整型数组,数组的大小由用户输入。接着程序会提示用户输入数组元素,程序将其存储在数组中,并输出数组元素。最后使用 delete[] 关键字释放动态分配的内存空间。
在以上代码中,int* 表示指向整型变量的指针,new int[size] 为分配内存空间的语句,该语句将返回一个指向分配的内存空间的指针。delete[] arr 为释放内存空间的语句。需要注意的是,使用动态数组时需要及时释放内存空间,否则会导致内存泄漏。
C++ 中的标准模板库提供了更加方便的动态数组实现方式,其中 vector 是最常用的容器。以下是 vector 的使用方法:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int size;
cout << "Enter the size of the array: ";
cin >> size;
vector<int> vec(size);
cout << "Enter " << size << " integers:" << endl;
for (int i = 0; i < size; i++) {
cin >> vec[i];
}
cout << "The array is: ";
for (int i = 0; i < size; i++) {
cout << vec[i] << " ";
}
cout << endl;
return 0;
}
vector 的使用方式与普通数组类似,但是 vector 的大小可以动态改变,不用担心内存空间不足的问题。vector 的成员函数 push_back() 可以在 vector 的末尾添加元素。vector 的成员函数 size() 可以获取当前 vector 的大小。vector 的成员函数 clear() 可以清空 vector 中的所有元素。