顺序表(vector)
结构定义
存储任意类型的连续空间
特点:
- 支持随机存取
- 插入删除操作繁琐
- 空间连续
typedef int data_type;
typedef struct vector {
data_type* data;
int size;
int length;
}vector;
//初始化
vector *init(int size) {
vector *vec = (vector *)calloc(sizeof(vector), 1);
vec->data = (data_type *)calloc(sizeof(data_type), size);
vec->size = size;
vec->length = 0;
return vec;
}
结构操作
扩容操作
扩容操作 : 当顺序表的连续存储空间不足时,使用realloc函数进行内存重新分配; 为了避免内存空间不足,可以在出现空间申请失败的时候将待申请空间缩小一倍;
int expand(vector *vec) {
int exp_size = vec->size;
data_type *p = NULL;
while (exp_size) {
p = (data_type *)realloc(vec->data, exp_size + vec->size);
if (p) break;
exp_size /= 2;
}
if (!p) return 0;
vec->size += exp_size;
vec->data = p;
return 1;
}
插入操作
插入操作指向之前需要提前判断ind的合法性, 避免非法访问, 同时判断剩余可插入空间是否充足, 不足扩容;另外注意顺序表插入操作需要将ind位置以及后面的元素挨个向后移动一位;
时间复杂度: O(n);
int insert(vector *vec, int ind, data_type val) {//插入操作
if (ind < 0 || ind > vec->length) return 0;
if (vec->length >= vec->size) {
//扩容
if (!expand(vec)) return 0;
printf("expand success ! => size = %d\n", vec->size);
}
for (int i = vec->length; i > ind; i--) {
vec->data[i] = vec->data[i - 1];
}
vec->data[ind] = val;
vec->length++;
return 1;
}
删除操作
删除操作指向前提前判断删除元素是否合法, 合法就将ind位置后面的元素挨个向前移动一个进行覆盖;
时间复杂度: O(n);
int erase(vector *vec, int ind) {
if (!vec || (ind < 0 || ind >= vec->length)) return 0;
for (int i = ind; i < vec->length - 1; i++) {
vec->data[i] = vec->data[i + 1];
}
vec->length--;
return 1;
}
查找操作
查找第ind位置上的元素, 可以先判断ind是否合法,合法就直接返回查找元素;
时间复杂度: O(1);
int find(vector *vec, int ind) {
return (ind < 0 || ind >= vec->length) ? -1 : vec->data[ind];
}
修改操作
修改第ind位置上的元素, 先判断ind位置是否合法, 合法就直接修改元素值;
时间复杂度: O(1);
int update(vector *vec, int ind, data_type val) {
return (ind < 0 || ind >= vec->length) ? -1 : (vec->data[ind] = val);
}
完整代码
/*************************************************************************
> File Name: 01.vector.c
> Author:
> Mail:
> Created Time: Sat 09 Mar 2024 08:41:42 PM CST
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef int data_type;
typedef struct vector {
data_type* data;
int size;
int length;
}vector;
vector *init(int size) {
vector *vec = (vector *)calloc(sizeof(vector), 1);
vec->data = (data_type *)calloc(sizeof(data_type), size);
vec->size = size;
vec->length = 0;
return vec;
}
int expand(vector *vec) {
int exp_size = vec->size;
data_type *p = NULL;
while (exp_size) {
p = (data_type *)realloc(vec->data, exp_size + vec->size);
if (p) break;
exp_size /= 2;
}
if (!p) return 0;
vec->size += exp_size;
vec->data = p;
return 1;
}
int insert(vector *vec, int ind, data_type val) {
if (ind < 0 || ind > vec->length) return 0;
if (vec->length >= vec->size) {
//扩容
if (!expand(vec)) return 0;
printf("expand success ! => size = %d\n", vec->size);
}
for (int i = vec->length; i > ind; i--) {
vec->data[i] = vec->data[i - 1];
}
vec->data[ind] = val;
vec->length++;
return 1;
}
int erase(vector *vec, int ind) {
if (!vec || (ind < 0 || ind >= vec->length)) return 0;
for (int i = ind; i < vec->length - 1; i++) {
vec->data[i] = vec->data[i + 1];
}
vec->length--;
return 1;
}
int find(vector *vec, int ind) {
return (ind < 0 || ind >= vec->length) ? -1 : vec->data[ind];
}
int update(vector *vec, int ind, data_type val) {
return (ind < 0 || ind >= vec->length) ? -1 : (vec->data[ind] = val);
}
void clear(vector *vec) {
if (!vec) return ;
free(vec->data);
free(vec);
return ;
}
void output(vector *vec) {
if (!vec) return ;
printf("| vec => | total = %d | [ ", vec->length);
for (int i = 0; i < vec->length; i++) {
i && printf(", ");
printf("%d", vec->data[i]);
}
printf(" ]\n");
return ;
}
int main() {
#define max_op 20
srand(time(0));//随机种子
int size = 5;
vector *vec = init(size);
for (int i = 0; i < max_op; i++) {
int op = rand() % 6;
int val = rand() % 100;
int ind = rand() % (vec->length + 3) - 1;
switch (op) {
case 0:
case 1:
case 2: {
printf("insert val = %d to ind = %d in vec = %d\n", val, ind, insert(vec, ind, val));
} break;
case 3: {
printf("erase ind = %d from vec = %d\n", ind, erase(vec, ind));
} break;
case 4: {
printf("find ind = %d in vec val = %d\n", ind, find(vec, ind));
} break;
case 5: {
printf("update ind %d in vec val = %d\n", ind, update(vec, ind, val));
} break;
}
output(vec);
}
#undef max_op
clear(vec);
return 0;
}