【学习记录】动态数组(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)数据结构,允许用户插入和删除元素,以及动态扩展数组的容量。以下是这段代码的主要功能:

  1. 结构体定义:

    • 定义了一个名为 vector 的结构体,包含了三个成员:
      • size:表示数组的容量。
      • count:表示数组中实际存储的元素数量。
      • data:是一个指向整数的指针,用于存储实际数据。
  2. 函数定义:

    • 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):删除指定位置的元素。
  3. 主函数 main

    • 使用 srand(time(0)) 初始化随机数种子,以确保随机数的不同性。
    • 创建一个名为 v 的 vector 对象,初始容量为 2。
    • 通过循环模拟进行一系列操作,最多执行 20 次。操作类型为随机选择,包括插入元素和删除元素。
    • 随机生成操作类型和操作位置,然后调用相应的函数进行插入或删除操作。
    • 每次操作后,输出当前 vector 的内容。
    • 最后,通过 clear(v) 清空 vector 对象并释放内存。

这段代码主要用于演示一个基本的动态数组的实现,以及如何进行插入和删除操作。在主函数中,通过随机操作来测试这些功能,以及展示 vector 内容的输出。