顺序表在算法中的应用--绪论

顺序表在算法中的应用

1. Basic situation

1.1 Sample code

//
// Created by 16624 on 2022/9/26.
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_OP 20


/**
 * @def 创建顺序表的数据结构
 * @Crition0502
 * @date 2022.9.26
 */
typedef struct vector{
    int size;
    int length;
    int *data; // 连续的存储区
} Vector;

/**
 * @def 初始化存储n个元素的顺序表
 * @param n
 * @return vec 分配好空间的顺序表的地址
 */
Vector *init(int n){
    // 开拓顺序表
    Vector *vec = (Vector *)malloc(sizeof(Vector));
    // 给顺序表开辟存储n个整数的存储空间
    vec->data = (int *)malloc(sizeof(int) * n);
    // 初始化顺序表的长度size以及当前存储的数据的数目length
    vec->size = n;
    vec->length = 0;
    return vec;
}

/**
 * @def 进行数据表的销毁
 * @param vec
 */
void Clear(Vector * vec){
    // 传入顺序表为空
    if(vec == NULL){
        return ;
    }

    // 不为空,进入顺序表的销毁
    free(vec->data);
    free(vec);
    return ;
}

/**
 * @def 进行顺序表的插入操作
 * @param vec
 * @param value
 * @param index
 * @return 0 | 1 0为插入失败,1为插入成功
 */
int Insert(Vector * vec , int value , int index){
    // 检测传入的参数是否合法
    if(vec == NULL) return 0;
    if(vec->length == vec->size) return 0;
    if(index < 0 || index > vec->length) return 0;

    // 进行插入操作
    // A. 不能从前进行往后的移动,因为这样的话会覆盖后面的数据导致出现bug
//    for(int i = index ; i < vec->length ; i++){
//        vec->data[i + 1] == vec->data[i];
//    }
    // B. 应该从后往前直到index位进行向后的移动操作
    for(int i = vec->length ; i > index ; i--){
        vec->data[i] = vec->data[i - 1];
    }
    vec->data[index] = value;
    vec->length += 1; // 记得给数组的当前存储数据的个数加个1哦!
    return 1;
}

/**
 * @def 进行顺序表的删除操作
 * @param vec
 * @param index
 * @return 0 | 1 0为插入失败,1为插入成功
 */
int Delete(Vector * vec , int index){
    // 检测传入的参数是否合法
    if(vec == NULL) return 0;
    if(vec->length == 0) return 0;
    if(index < 0 || index >= vec->length) return 0;
    // 进行顺序表的删除操作(循环向前)
    for(int i = index + 1 ; i < vec->length ; i++){
        vec->data[i - 1] = vec->data[i];
    }
    vec->length -= 1;
    return 1;
}

/**
 * @def 遍历顺序表打印出来
 * @param vec
 */
void PrintVector(Vector *vec){
    printf("Vector(%d) = [" , vec->length);
    for(int i = 0 ; i < vec->length ; i++){
        if(i != 0) printf(", ");
        printf("%d" , vec->data[i]);
    }
    printf("]\n");
    return ;
}

int showMain ()
{
    // 生成随机时间种子
    srand(time(0));

    Vector *vec = init(MAX_OP);

    int op , index , value = 0;
    for(int i = 0 ; i < MAX_OP ; i++){
        op = rand() % 2; // 产生的数字为0 | 1
        index = rand() % (vec->length + 1);
        value = rand() % 100;
        switch(op){
            case 0:
                printf("Insert %d at %d to vector.\n" , value , index);
                Insert(vec , value , index);
                break;
            case 1:
                printf("Erase the value at %d from vector.\n" , index);
                Delete(vec , index);
                break;
        }
        PrintVector(vec);
    }

    return 0;
}

1.2 Disadvantage:

A. 避免了数组的限定长度的缺陷

B. 但还是不能在长度受限的时候进行动态的内存分配

2. Advanced code

2.1 对于内存动态分配进行了增强

//
// Created by 16624 on 2022/9/26.
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_OP 20


/**
 * @def 创建顺序表的数据结构
 * @Crition0502
 * @date 2022.9.26
 */
typedef struct vector{
    int size;
    int length;
    int *data; // 连续的存储区
} Vector;

/**
 * @def 初始化存储n个元素的顺序表
 * @param n
 * @return vec 分配好空间的顺序表的地址
 */
Vector *init(int n){
    // 开拓顺序表
    Vector *vec = (Vector *)malloc(sizeof(Vector));
    // 给顺序表开辟存储n个整数的存储空间
    vec->data = (int *)malloc(sizeof(int) * n);
    // 初始化顺序表的长度size以及当前存储的数据的数目length
    vec->size = n;
    vec->length = 0;
    return vec;
}

/**
 * @def 进行数据表的销毁
 * @param vec
 */
void Clear(Vector * vec){
    // 传入顺序表为空
    if(vec == NULL){
        return ;
    }

    // 不为空,进入顺序表的销毁
    free(vec->data);
    free(vec);
    return ;
}

/**
 * @def 拓展顺序表的储存空间
 * @param vec
 * @return 0 | 1 0为插入失败,1为插入成功
 */
int Expand(Vector * vec){
    vec->size *= 2;
    vec->data = (int *)realloc(vec->data , sizeof(int) * vec->size);
    return 1;
}

/**
 * @def 进行顺序表的插入操作
 * @param vec
 * @param value
 * @param index
 * @return 0 | 1 0为插入失败,1为插入成功
 */
int Insert(Vector * vec , int value , int index){
    // 检测传入的参数是否合法
    if(vec == NULL) return 0;
    // 扩容操作
    if(vec->length == vec->size){
        if(!Expand(vec)) return 0;
        printf("Expand success! Now the size is %d\n" , vec->size);
    }
    if(index < 0 || index > vec->length) return 0;

    // 进行插入操作
    // A. 不能从前进行往后的移动,因为这样的话会覆盖后面的数据导致出现bug
//    for(int i = index ; i < vec->length ; i++){
//        vec->data[i + 1] == vec->data[i];
//    }
    // B. 应该从后往前直到index位进行向后的移动操作
    for(int i = vec->length ; i > index ; i--){
        vec->data[i] = vec->data[i - 1];
    }
    vec->data[index] = value;
    vec->length += 1; // 记得给数组的当前存储数据的个数加个1哦!
    return 1;
}

/**
 * @def 进行顺序表的删除操作
 * @param vec
 * @param index
 * @return 0 | 1 0为插入失败,1为插入成功
 */
int Delete(Vector * vec , int index){
    // 检测传入的参数是否合法
    if(vec == NULL) return 0;
    if(vec->length == 0){
        if(!Expand(vec)) return 0;
        printf("Expand success! Now the sie is %d\n" , vec->size);
    }
    if(index < 0 || index >= vec->length) return 0;
    // 进行顺序表的删除操作(循环向前)
    for(int i = index + 1 ; i < vec->length ; i++){
        vec->data[i - 1] = vec->data[i];
    }
    vec->length -= 1;
    return 1;
}

/**
 * @def 遍历顺序表打印出来
 * @param vec
 */
void PrintVector(Vector *vec){
    printf("Vector(%d) = [" , vec->length);
    for(int i = 0 ; i < vec->length ; i++){
        if(i != 0) printf(", ");
        printf("%d" , vec->data[i]);
    }
    printf("]\n");
    return ;
}

int showMain ()
{
    // 生成随机时间种子
    srand(time(0));

    Vector *vec = init(1);

    int op , index , value = 0;
    for(int i = 0 ; i < MAX_OP ; i++){
        op = rand() % 2; // 产生的数字为0 | 1
        index = rand() % (vec->length + 1);
        value = rand() % 100;
        switch(op){
            case 0:
                printf("Insert %d at %d to vector.\n" , value , index);
                Insert(vec , value , index);
                break;
            case 1:
                printf("Erase the value at %d from vector.\n" , index);
                Delete(vec , index);
                break;
        }
        PrintVector(vec);
    }

    return 0;
}

--------------------------------------------------------------------------
Output:
Insert 77 at 0 to vector.
Vector(1) = [77]
Erase the value at 0 from vector.
Vector(0) = []
Insert 75 at 0 to vector.
Vector(1) = [75]
Insert 88 at 1 to vector.
Expand success! Now the size is 2
Vector(2) = [75, 88]
Insert 63 at 0 to vector.
Expand success! Now the size is 4
Vector(3) = [63, 75, 88]
Erase the value at 0 from vector.
Vector(2) = [75, 88]
Erase the value at 1 from vector.
Vector(1) = [75]
Insert 28 at 0 to vector.
Vector(2) = [28, 75]
Erase the value at 2 from vector.
Vector(2) = [28, 75]
Erase the value at 0 from vector.
Vector(1) = [75]
Insert 4 at 0 to vector.
Vector(2) = [4, 75]
Insert 2 at 0 to vector.
Vector(3) = [2, 4, 75]
Insert 7 at 3 to vector.
Vector(4) = [2, 4, 75, 7]
Erase the value at 2 from vector.
Vector(3) = [2, 4, 7]
Insert 80 at 2 to vector.
Vector(4) = [2, 4, 80, 7]
Erase the value at 0 from vector.
Vector(3) = [4, 80, 7]
Insert 31 at 1 to vector.
Vector(4) = [4, 31, 80, 7]
Insert 93 at 0 to vector.
Expand success! Now the size is 8
Vector(5) = [93, 4, 31, 80, 7]
Erase the value at 1 from vector.
Vector(4) = [93, 31, 80, 7]
Insert 37 at 2 to vector.
Vector(5) = [93, 31, 37, 80, 7]

进程已结束,退出代码0  

2.2 但是内存分配的时候仍会出现内存泄漏的问题

改写了Expand函数的分配内存的逻辑关系

int Expand(Vector * vec){
    int new_size = vec->size * 2;
    int *p = (int *)realloc(vec->data , sizeof(int) * new_size);
    if(p == NULL){
        return 0;
    }else{
        vec->size = new_size;
        vec->data = p;
        return 1;
    }
}

The end

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值