【学习记录】动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。用C语言编写
#include <iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
// 我的代码所犯的错误记录:
// 1. \n的换行打成了/n导致程序迟迟不能换行
// 2. rand()%4,是随机0~3的随机数,并不是0~4
// 3. 在main主函数中,首先声明int pos, val;如果在下方执行函数继续声明int pos, val;会导致变量初始化,从而使int pos, val这两个变量再次刷新,导致随机插入值不对
// 4. for循环的使用规则,内部变量i必须初始化为int类型,不然会报错
// 定义自定义结构体 vector,用于模拟动态数组
typedef struct vector
{
int size; // 数组容量
int count; // 数组元素数量
int* data; // 指向数据的指钨
} vector;
// 创建一个新的 vector,n 表示初始容量
vector* getNewvector(int n) {
vector* p = (vector*)malloc(sizeof(vector)); // 分配 vector 结构体内存
p->size = n;
p->count = 0; // 初始化元素数量为 0
p->data = (int*)malloc(sizeof(int) * n); // 分配数据存储内存
return p;
}
// 扩展 vector 的容量
int expand(vector* v) {
if (v == NULL) return 0; // 检查传入参数是否为空
int* p = (int*)realloc(v->data, sizeof(int) * 2 * v->size); // 重新分配内存为原来的两倍
if (p == NULL) return 0; // 检查内存分配是否成功
v->data = p;
v->size *= 2;
return 1;
}
// 插入元素到指定位置
int insert(vector* v, int pos, int val) {
if (pos < 0 || pos > v->count) return 0; // 检查插入位置是否有效
if (v->size == v->count && !expand(v)) {
return 0; // 检查容量是否足够,不足则扩展失败返回0
}
for (int i = v->count - 1; i >= pos; i--){
v->data[i + 1] = v->data[i]; // 将元素后移
}
v->data[pos] = val; // 插入新元素
v->count += 1; // 增加元素数量
return 1;
}
// 清空 vector,释放内存
void clear(vector *v){
if (v == NULL) return;
free(v->data);
free(v);
return;
}
// 输出 vector 中的内容
void output_vector(vector* v){
int len = 0;
for(int i = 0; i < v->size; i++){
len += printf("%3d", i);
}
printf("\n");
for (int i = 0; i < len; i++){ printf("-"); }
printf("\n");
for (int i = 0; i < v->count; i++) {
printf("%3d", v->data[i]);
}
printf("\n\n");
return;
}
// 删除指定位置的元素
int erase(vector* v, int pos) {
if (pos < 0 || pos >= v->count) return 0; // 检查删除位置是否有效
for (int i = pos + 1; i < v->count; i++) {
v->data[i - 1] = v->data[i]; // 将元素前移
}
v->count -= 1; // 减少元素数量
return 1;
}
int main() {
srand(time(0)); // 使用当前时间作为随机数种子
#define MAX_OP 20
vector* v = getNewvector(2); // 创建一个初始容量为2的 vector
for (int i = 0; i < MAX_OP; i++) {
int op = rand() % 4, pos, val, ret; // 随机生成操作类型,位置,值
switch (op)
{
case 0:
case 1:
case 2:
pos = rand() % (v->count+2); // 随机生成插入位置
val = rand() % 100; // 随机生成插入值
ret = insert(v, pos, val); // 插入操作
printf("insert %d at %d to vector = %d\n",val, pos, ret);
break;
case 3:
pos = rand() % (v->count + 2); // 随机生成删除位置
ret = erase(v, pos); // 删除操作
printf("erase item at %d in vector = %d\n", pos, erase(v, pos));
break;
}
output_vector(v); // 输出当前 vector 内容
}
clear(v); // 清空 vector 并释放内存
return 0;
}
这段代码实现了一个简单的动态数组(vector)数据结构,允许用户插入和删除元素,以及动态扩展数组的容量。以下是这段代码的主要功能:
-
结构体定义:
- 定义了一个名为
vector
的结构体,包含了三个成员:size
:表示数组的容量。count
:表示数组中实际存储的元素数量。data
:是一个指向整数的指针,用于存储实际数据。
- 定义了一个名为
-
函数定义:
getNewvector(int n)
:用于创建一个新的 vector 对象,初始容量为 n。expand(vector* v)
:扩展 vector 的容量,使其容量变为原来的两倍。insert(vector* v, int pos, int val)
:在指定位置插入一个值为 val 的元素。clear(vector *v)
:释放 vector 对象占用的内存,包括数据数组和 vector 结构体本身。output_vector(vector* v)
:以漂亮的格式输出 vector 中的内容。erase(vector* v, int pos)
:删除指定位置的元素。
-
主函数
main
:- 使用
srand(time(0))
初始化随机数种子,以确保随机数的不同性。 - 创建一个名为
v
的 vector 对象,初始容量为 2。 - 通过循环模拟进行一系列操作,最多执行 20 次。操作类型为随机选择,包括插入元素和删除元素。
- 随机生成操作类型和操作位置,然后调用相应的函数进行插入或删除操作。
- 每次操作后,输出当前 vector 的内容。
- 最后,通过
clear(v)
清空 vector 对象并释放内存。
- 使用
这段代码主要用于演示一个基本的动态数组的实现,以及如何进行插入和删除操作。在主函数中,通过随机操作来测试这些功能,以及展示 vector 内容的输出。