数据结构复习之实现一个顺序表结构的线性表

157 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

实现一个会动态扩容,没有元素上线的顺序表.

image.png

image.png

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

// 顺序表的定义
typedef  struct vector {
    int *data; // data:存储的元素
    int size, cap; // size:顺序表的长度;cap: 容量上限
} vector;

// 初始化: 初始化一个vector(动态分配的),动态分配好之后返回指针
// cnt:容量上限
vector *init (int cnt) {
    // 申请一片顺序表vector结构的空间
    vector *p = (vector *) malloc(sizeof(vector));
    p->data = (int *) malloc(sizeof(int) * cnt);
    p->size = 0;
    p->cap = cnt;
    return  p;
}
// 销毁: 先销毁后申请的空间.—— 如果先销毁p,因为p->data也是它申请的,如果销毁了p,那么p->data就访问不到了
// 释放顺序与申请顺序相反
void delete_vector(vector *p) {
    free(p->data);
    free(p);
}

// 输出顺序表中所有元素
void show_vector (vector *v) {
    printf("---------size = %d, cap = %d---------\n", v->size, v->cap);
    for (int i = 0; i < v->size; i++) {
        printf("%d ", v->data[i]);
    }
    printf("\n------------------------------\n");
}

// 插入: 根据下标插入元素
int insert_ele(vector *v, int ind, int val) {
    if (ind > v->size) { // 1.如果插入位置大于表中的元素,中间会隔个数字
        return 1; // 插入失败
    }
//    2. 判断容量是否达到上限。 如果容量存满了则扩容,扩容到原来的2倍
    if (v->size == v->cap) {
        v->cap *= 2; //扩容: 容量上限变为原来的2倍
        // realloc(①, ②); realloc会将后面第一个参数的空间重新分配为第二个参数的大小。如果可以直接申请就直接申请,如果不能,会申请一片新的空间,在将原本的数据移过去
        v->data = (int *)realloc(v->data, sizeof(int) * v->cap);
    }
    // 3.移动元素:将后面的元素依次向后移动
    for (int i = v->size; i > ind; i--) {
        v->data[i] = v->data[i-1];
    }
    v->data[ind] = val; // 在下标ind位置插入元素val
    v->size++; // 4. 修改size值
    return 0; // 插入成功
}
/**
 * 删除元素
 * v: 要删除的顺序表
 * ind:要删除元素的下标
 * */
int delete_ele(vector *v, int ind) {
    // 1. 判断要删除的元素是否存在
    if (v->size <= ind ) {
        return 1;// 删除失败
    }
    // 2. 删除:从前向后覆盖元素
    for (int i = ind; i < v->size - 1; i++) {
        v->data[i] = v->data[i + 1]; // 将后面的值存到前面,进行覆盖
    }
    // 3. 修改size的值
    v->size--;
    return 0; // 删除成功
}


/**
 * 操作
 * 0:插入, 在ind位置插入val
 * 1:删除,删除ind位置的元素
 * */
int main() {
    int n, cnt; // n: 操作次数,cnt:容量上限
    scanf("%d%d", &n, &cnt);
    vector *v = init(cnt); // 初始化
    for (int i = 0; i < n; i++) {
        int a, b;
        scanf("%d", &a); // 是要插入还是删除
        if (a == 0) { // 插入
            scanf("%d%d", &a, &b); // ind:a val:b
            insert_ele(v, a, b); // 在顺序表v中,下标为a的位置插入一个元素b. ———— 无法”飞跃“插入
        } else if (a == 1) { // 删除 ind:a
            scanf("%d", &a); // 输入要删除的元素下标
            delete_ele(v, a); // 在顺序表v中, 删除下标为a的位置元素
        }
        show_vector(v); // 每次操作完之后,打印顺序表
    }
    delete_vector(v); // 销毁
    v = NULL;
    return 0;
}