顺序表
结构定义
typedef struct Vector {
int *date;
int size, length;
} Vector;
C 语言提供了 typedef 关键字,可以使用它来为类型取一个新的名字。
结构操作
创建
typedef struct Vector {
int *date;
int size, length;
} Vector;
int *date
记录的是首地址
清除顺序表
void clear(Vector *v) {
if (v == NULL) return ;
free(v->date);
free(v);
return ;
}
首先清除v->date
,再清除v; 这样可以防止内存泄漏;
如果先清除v
,则free(v->date)
回报错。
打印顺序表
void output(Vector *v) {
if (v == NULL) return ;
printf("Vector: [");
for (int i = 0; i <= v->length; i++) {
i && printf(" ");
printf("%d", v->date[i]);
}
printf("]");
return ;
}
技巧:i && printf(" ")
控制空格的输出,当i=0
时,由于&&
的提前判断,使得 printf(" ")
不会被执行。
元素的插入
int insert(Vector *v, int ind, int val) {
if (v == NULL) return 0;
if(v->length == v->size) {
if(!expand(v)) return 0;
printf(GREEN("success to expand! the size = %d\n"), v->size);
}
if (ind < 0 || ind > v->length) return 0;
for (int i = v->length; i > ind; i--) {
v->date[i] = v->date[i-1];
}
v->date[ind] = val;
v->length += 1;
return 1;
}
当length不足时,申请扩容,若扩容成功,则返回1;若扩容失败,则返回0,通过if(!expand(v)) return 0;
退出insert函数。
当length足够的时间,从后向前覆盖即可移动数据,最后赋值并真加长度即可。
元素的清除
int erase(Vector *v, int ind) {
if (v == NULL) return 0;
if (ind < 0 || ind > v->length) return 0;
for (int i = ind + 1; i < v->length; i++) {
v->date[i -1] = v->date[i];
}
v->length -= 1;
return 1;
}
从前向后覆盖。末尾处向前覆盖后,在原位置有内存上的残留,但由于length的减小,使得并不访问到。
-
错误写法:
for (int i = ind ; i < v->length; i++) { v->date[i] = v->date[i + 1]; }
date[i + 1]
当i = v->length
会产生访问的越界。
-
正确写法:
for (int i = ind + 1; i < v->length; i++) { v->date[i -1] = v->date[i]; }
扩容操作
int expand(Vector *v) {
int extr_size = v->size;
int *p;
while (extr_size) {
p =(int *)realloc(v->date, sizeof(int) * (v->size + extr_size));
if(p != NULL) break;
extr_size >> 1;
}
if (p == NULL) return 0;
v->date = p;
v->size += extr_size;
return 1;
}
malloc
: 动态申请的内存没有初始化。calloc
:动态申请内存并且初始化为0 。realloc
:尝试重新调整之前调用malloc
或calloc
所分配的内存块的大小。尝试失败返回NULL
。
测试模块
int main() {
srand(time(0));
#define MAX_OP 20
Vector *v = init(1);
for (int i = 0; i < MAX_OP; i++) {
int op = rand() % 4;
int val = rand() % 100;
int ind = rand() % (v->length + 3) - 1;
switch (op) {
case 0:
case 1:
case 2: {
printf("insert %d at %d to Vector = %d\n", val, ind, insert(v, ind, val));
} break;
case 3: {
printf("erase a item at %d from Vector = %d\n", ind, erase(v, ind));
} break;
}
output(v), printf("\n");
}
#undef MAX_OP
clear(v);
return 0;
}
其它
颜色设置
#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)
完整代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)
typedef struct Vector {
int *date;
int size, length;
} Vector;
Vector *init(int n) {
Vector *v = (Vector *)malloc (sizeof(Vector));
v->date = (int *)malloc(sizeof(int) * n);
v->length = 0;
v->size = n;
return v;
}
int expand(Vector *v) {
int extr_size = v->size;
int *p;
while (extr_size) {
p =(int *)realloc(v->date, sizeof(int) * (v->size + extr_size));
if(p != NULL) break;
extr_size >> 1;
}
if (p == NULL) return 0;
v->date = p;
v->size += extr_size;
return 1;
}
void clear(Vector *v) {
if (v == NULL) return ;
free(v->date);
free(v);
return ;
}
int insert(Vector *v, int ind, int val) {
if (v == NULL) return 0;
if(v->length == v->size) {
if(!expand(v)) return 0;
printf(GREEN("success to expand! the size = %d!!!!!!!!!!!!\n"), v->size);
}
if (ind < 0 || ind > v->length) return 0;
for (int i = v->length; i > ind; i--) {
v->date[i] = v->date[i-1];
}
v->date[ind] = val;
v->length += 1;
return 1;
}
int erase(Vector *v, int ind) {
if (v == NULL) return 0;
if (ind < 0 || ind > v->length) return 0;
for (int i = ind + 1; i < v->length; i++) {
v->date[i -1] = v->date[i];
}
v->length -= 1;
return 1;
}
void output(Vector *v) {
if (v == NULL) return ;
printf("Vector: [");
for (int i = 0; i <= v->length; i++) {
i && printf(" ");
printf("%d", v->date[i]);
}
printf("]");
return ;
}
int main() {
srand(time(0));
#define MAX_OP 20
Vector *v = init(1);
for (int i = 0; i < MAX_OP; i++) {
int op = rand() % 4;
int val = rand() % 100;
int ind = rand() % (v->length + 3) - 1;
switch (op) {
case 0:
case 1:
case 2: {
printf("insert %d at %d to Vector = %d\n", val, ind, insert(v, ind, val));
} break;
case 3: {
printf("erase a item at %d from Vector = %d\n", ind, erase(v, ind));
} break;
}
output(v), printf("\n");
}
#undef MAX_OP
clear(v);
return 0;
}