[Data structure] The basic operations of dynamic array (vector), including insertion, deletion, expansion, output, release of memory, etc. Here is an explanation and comments of the code:

This C code implements the basic operations of a dynamic array (vector), including insertion, deletion, expansion, output, and release of memory. Here is an explanation and comments of the code:

// 引入标准输入输出库和标准库函数,用于后续的内存分配和打印输出等操作  
#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;  
}  
  

// 定义一个名为output_vector的函数,它接受一个指向vector结构体的指针作为参数  
void output_vector(vector* v) {  
  
    // 初始化一个整型变量len,用于存储要输出的整数之和  
    int len = 0;  
  
    // 遍历vector的大小(即其可以容纳的元素数量)  
    for (int i = 0; i < v->size; i++) {  
        // 在每次循环中,将整数i的值加到len上,同时输出i的值(格式化为三个数字宽)  
        len += printf("%3d", i);  
    }  
  
    // 输出一个换行符  
    printf("\n");  
  
    // 根据前面输出的整数数量,输出相应数量的短横线(-)以形成一个框架  
    for (int i = 0; i < len; i++) printf("-");  
  
    // 再输出一个换行符  
    printf("\n");  
  
    // 遍历vector中的元素(只遍历实际存在的元素,即count个)  
    for (int i = 0; i < v->count; i++) {  
        // 输出vector中第i个元素的值(格式化为三个数字宽)  
        printf("%3d", v->data[i]);  
    }  
  
    // 输出一个换行符  
    printf("\n");  
  
    // 输出两个空行,可能是为了创建视觉分隔或提供一些视觉清晰度  
    printf("\n\n");  
  
    // 函数结束,返回无值(void)  
    return;  
} 
  
// 释放动态数组内存  
void clear(vector *v) {  
    // 如果传入的指针为NULL,则直接返回,不进行任何操作  
    if (v == NULL) return ;  
    // 释放data指针指向的内存空间  
    free(v->data);  
    // 释放v指针指向的内存空间  
    free(v);  
    // 返回  
    return ;  
}  
  
// 程序从main函数开始执行  
int main() {  
    // 使用当前时间作为随机数生成器的种子,这样可以使得每次运行程序时生成的随机数都不同  
    srand(time(0));  
      
    // 定义常量MAX_OP为20,表示要进行的操作次数  
    #define MAX_OP 20  
  
    // 调用getNewVector函数创建一个新的动态数组,并返回指向该数组的指针,数组的大小为2  
    vector *v = getNewVector(2);  
  
    // 执行MAX_OP次循环,每次循环都会随机生成一个操作和相应的参数  
    for (int i = 0; i < MAX_OP; i++) {  
        // 生成一个介于0到3之间的随机数,这个随机数将用于决定执行哪种操作  
        int op = rand() % 4, pos, val, ret;  
          
        // 根据随机数决定执行哪种操作  
        switch (op) {  
            // 如果操作是0、1或2,表示要进行插入操作  
            case 0:  
            case 1:  
            case 2:  
                // 生成一个介于0到(数组大小+1)之间的随机数,作为插入位置  
                pos = rand() % (v->count + 2);  
                // 生成一个介于0到99之间的随机数,作为要插入的值  
                val = rand() % 100;  
                // 调用insert函数进行插入操作,并把返回值保存在ret变量中  
                ret = insert(v, pos, val);  
                // 输出插入操作的信息,包括插入的值、插入的位置以及插入是否成功的返回值  
                printf("insert %d at %d to vector = %d\n", val, pos, ret);  
                break;  
            // 如果操作是3,表示要进行删除操作  
            case 3:  
                // 生成一个介于0到(数组大小+1)之间的随机数,作为删除位置  
                pos = rand() % (v->count + 2);  
                // 调用erase函数进行删除操作,并把返回值保存在ret变量中  
                ret = erase(v, pos);  
                // 输出删除操作的信息,包括删除位置以及删除是否成功的返回值  
                printf("erase item at %d in vector = %d\n", pos, ret);  
                break;  
        }  
        // 输出当前动态数组的内容  
        output_vector(v);  
    }  
    // 调用clear函数释放动态数组所占用的内存空间  
    clear(v);  
    // 程序正常结束,返回0  
    return 0;  
}

This code implements a simple dynamic array (vector), including the functions of inserting, deleting and printing array elements. The following is a functional explanation of each function:

  1. getNewVector(int n): This function creates a new dynamic array and allocates the specified amount of integer storage for it. It returns a pointer to the newly created dynamic array.
  2. expand(vector *v): This function is used to double the storage space of the dynamic array. If the current storage space is sufficient, then it does nothing. Otherwise, it uses  realloc the function to reallocate storage twice the current size and copy the old data to the new storage. It returns 0 if expanding storage fails, 1 otherwise.
  3. insert(vector *v, int pos, int val): This function inserts a new element in the dynamic array. It first checks whether the inserted position is valid, and then checks whether the storage space needs to be expanded. It returns 0 if the storage needs to be expanded and the expansion operation fails. Otherwise, it shifts all elements in the array back one bit, and then inserts the new element at the specified position. Finally, it will return 1 to indicate a successful insertion.
  4. erase(vector *v, int pos): This function deletes an element from the dynamic array. It first checks that the deleted position is valid, then deletes the element and returns 1 to indicate successful deletion.
  5. output_vector(vector *v): This function prints all elements of the dynamic array and their positions (including empty slots).
  6. clear(vector *v): This function releases the memory space of the dynamic array.

Guess you like

Origin blog.csdn.net/dsafefvf/article/details/132677564