【数据结构】动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释:

这段C代码实现了一个动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释:

cpp 复制代码
// 引入标准输入输出库和标准库函数,用于后续的内存分配和打印输出等操作  
#include <stdio.h>  
#include <stdlib.h>  
  
// 引入时间库,用于生成随机数(这里并未使用,但保留了引入头文件)  
#include <time.h>  
  
// 定义一个名为vector的结构体,该结构体有三个成员:size表示数组的大小,count表示数组中元素的数量,data是一个指向整型数组的指针,存储数组中的元素  
typedef struct vector {  
    int size, count;  
    int *data;  
} vector;  
  
// getNewVector函数用于创建一个新的动态数组,并返回其指针  
vector *getNewVector(int n) {  
    // 使用malloc函数为vector结构体分配内存  
    vector *p = (vector *)malloc(sizeof(vector));  
    // 设置新创建的vector的大小为n,元素数量为0,并为data指针分配n个int类型的内存空间  
    p->size = n;  
    p->count = 0;  
    p->data = (int *)malloc(sizeof(int) * n);  
    // 返回新创建的vector的指针  
    return p;  
}  
  
// expand函数用于扩容动态数组,将数组的大小翻倍  
int expand(vector *v) {  
    // 检查传入的指针是否为空,如果为空则返回0  
    if (v == NULL) return 0;  
    // 打印一条消息表示开始扩容  
    printf("expand v from %d to %d\n", v->size, 2 * v->size);  
    // 使用realloc重新分配足够的内存来存储int类型的2n个元素,并将这些元素的地址赋值给data指针  
    int *p = (int *)realloc(v->data, sizeof(int) * 2 * v->size);  
    // 如果realloc失败(返回NULL),则返回0;否则,将新分配的内存地址赋值给data,将数组的大小乘以2,并返回1表示扩容成功  
    if (p == NULL) return 0;  
    v->data = p;  
    v->size *= 2;  
    return 1;  
}  
  
// insert函数用于在动态数组的指定位置插入一个元素  
int insert(vector *v, int pos, int val) {  
    // 检查插入的位置是否合法,如果不合法则返回0  
    if (pos < 0 || pos > v->count) return 0;  
    // 检查数组是否需要扩容,如果需要扩容但是扩容失败则返回0  
    if (v->size == v->count && !expand(v)) return 0;  
    // 从数组的末尾开始向前遍历每个元素,将每个元素向后移动一个位置  
    for (int i = v->count - 1; i >= pos; i--) {  
        v->data[i + 1] = v->data[i];  
    }  
    // 在指定的位置插入新的元素  
    v->data[pos] = val;  
    // 将元素数量加1,然后返回1表示插入成功  
    v->count += 1;  
    return 1;  
}  
  
// erase函数用于从动态数组中删除指定位置的元素  
int erase(vector *v, int pos) {  
    // 检查删除的位置是否合法,如果不合法则返回0  
    if (pos < 0 || pos >= v->count) return 0;  
    // 从删除位置的下一个位置开始遍历每个元素,将每个元素向前移动一个位置  
    for (int i = pos + 1; i < v->count; i++) {  
        v->data[i - 1] = v->data[i];  
    }  
    // 将元素数量减1,然后返回1表示删除成功  
    v->count -= 1;  
    return 1;  
}  
  

// 输出动态数组的内容  
void output_vector(vector *v) {  
    int len = 0;  
    // 计算数组中所有位置的长度,包括空位  
    for (int i = 0; i < v->size; i++) {  
        len += printf("%3d", i);  
    }  
    // 打印一个换行符  
    printf("\n");  
    // 打印长度为len的"-"字符,表示空位  
    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");  
    printf("\n\n");  
    // 返回  
    return ;  
}  
  
// 释放动态数组内存  
void clear(vector *v) {  
    // 如果传入的指针为NULL,则直接返回,不进行任何操作  
    if (v == NULL) return ;  
    // 释放data指针指向的内存空间  
    free(v->data);  
    // 释放v指针指向的内存空间  
    free(v);  
    // 返回  
    return ;  
}  
  
// 主函数  
int main() {  
    // 使用当前时间作为随机数种子,以保证每次运行程序时随机数不同  
    srand(time(0));  // 初始化随机数种子  
    // 定义常量MAX_OP表示最大操作次数  
    #define MAX_OP 20  // 最大操作次数  
    // 创建一个初始大小为2的动态数组,并返回其指针  
    vector *v = getNewVector(2);  // 创建一个初始大小为2的动态数组  
    // 循环执行MAX_OP次操作  
    for (int i = 0; i < MAX_OP; i++) {  
        // 随机生成一个操作码op,取值范围为0-3  
        int op = rand() % 4, pos, val, ret;  
        // 根据操作码执行不同的操作  
        switch (op) {  
            case 0:  // 插入操作  
            case 1:  // 插入操作  
            case 2:  // 插入操作  
                // 随机生成一个位置pos,取值范围为0到count+2(包括count+2)  
                pos = rand() % (v->count + 2);  
                // 随机生成一个值val,取值范围为0到100(包括100)  
                val = rand() % 100;  
                // 调用insert函数在指定位置插入元素val,并返回结果ret  
                ret = insert(v, pos, val);  
                // 打印插入操作的结果,包括插入的值、位置以及返回值  
                printf("insert %d at %d to vector = %d\n",   
                    val, pos, ret);  
                break;  // 跳出switch语句的当前case分支,准备执行下一个case分支或者结束switch语句  
            case 3:  // 删除操作  
                // 随机生成一个位置pos,取值范围为0到count+2(包括count+2)  
                pos = rand() % (v->count + 2);  
                // 调用erase函数在指定位置删除元素,并返回结果ret  
                ret = erase(v, pos);  
                // 打印删除操作的结果,包括删除的位置以及返回值  
                printf("erase item at %d in vector = %d\n",   
                    pos, ret);  
                break;  // 跳出switch语句的当前case分支,准备执行下一个case分支或者结束switch语句  
        }  
        // 输出当前动态数组的内容,包括空位和元素值  
        output_vector(v);  
    }  
    // 释放动态数组的内存空间,包括data指针和v指针指向的内存空间  
    clear(v);  // 释放动态数组内存  
    // 主函数结束,返回0表示程序正常退出  
    return 0;  
}

这段代码实现了一个简单的动态数组(vector),包含插入、删除和打印数组元素的功能。下面是各个函数的功能解释:

  1. getNewVector(int n):这个函数创建了一个新的动态数组,并为其分配了指定数量的整数存储空间。它返回一个指向新创建的动态数组的指针。
  2. expand(vector *v):这个函数用于将动态数组的存储空间扩大一倍。如果当前的存储空间已经足够,那么它什么都不做。否则,它会使用 realloc 函数来重新分配两倍于当前大小的存储空间,并将旧的数据复制到新的存储空间。如果扩大存储空间失败,它会返回0,否则返回1。
  3. insert(vector *v, int pos, int val):这个函数在动态数组中插入一个新的元素。它首先检查插入的位置是否有效,然后检查是否需要扩大存储空间。如果需要扩大存储空间且扩大操作失败,它会返回0。否则,它会将数组中的所有元素向后移动一位,然后在指定的位置插入新的元素。最后,它会返回1表示插入成功。
  4. erase(vector *v, int pos):这个函数从动态数组中删除一个元素。它首先检查删除的位置是否有效,然后删除元素并返回1表示删除成功。
  5. output_vector(vector *v):这个函数打印动态数组的所有元素和它们的位置(包括空位)。
  6. clear(vector *v):这个函数释放动态数组的内存空间。
相关推荐
好记性+烂笔头18 分钟前
hot100-438. 找到字符串中所有字母异位词
算法
别耗尽31 分钟前
错题集锦之C语言
c语言
六点半88831 分钟前
【C/C++】速通涉及string类的经典编程题
c语言·开发语言·c++·算法
Jack黄从零学c++1 小时前
自制网络连接工具(支持tcpudp,客户端服务端)
linux·c语言·开发语言·网络协议·tcp/ip·udp·信息与通信
day3ZY1 小时前
清理C盘缓存,电脑缓存清理怎么一键删除,操作简单的教程
c语言·开发语言·缓存
学地理的小胖砸2 小时前
【高分系列卫星简介】
开发语言·数码相机·算法·遥感·地理信息
yanyanwenmeng2 小时前
matlab基础
开发语言·算法·matlab
##晴天小猪2 小时前
ByteTrack多目标跟踪流程图
人工智能·算法·目标检测·机器学习·目标跟踪
白帽黑客cst2 小时前
网络安全(黑客技术) 最新三个月学习计划
网络·数据结构·windows·学习·安全·web安全·网络安全
ly-how3 小时前
leetcode练习 二叉树的层序遍历
算法·leetcode