顺序表
顺序表的结构定义
一种更高级的数组,一片连续存储空间存储元素,存储任意类型的元素,但是不能混着存
定义三个关键参数:
size:数组空间大小
length:已具有元素多少,存了多少个
data_type:存的类型
操作:插入、删除
插入:插到中间,就意味着后面的元素都要往后移动,最安全的做法是从最后开始向后移动,完成后关键参数需要修改(length修改)
删除:告诉计算机该空间是可以修改的,因此可以用后面的覆盖掉前面的,同样最后需要修改length。
动态扩容
malloc:管开不管置零
calloc:管开也管置零,但不能扩容
realloc:管开管埋管扩容,扩容格式
example:
(int *)realloc(vec->data, sizeof(vec->length + extr_length));
顺序表的一个例子:
实现一个int类型的顺序表,需要执行插入、清除、扩容、回收内存的操作。
/* 思路:
初始化:返回顺序表的首地址
顺序表的销毁操作:是否存在,释放哪片空间
插入操作:传去哪里,传什么,插在哪里
判断能否插入(操作是否违法)
将插入位置之后的所有元素向后移动一位
完成之后插入
插入完成之后修改length
删除操作:删谁的,删哪
判断是否合法
删除位后面的覆盖掉前面的
修改length
输出顺序表操作:明确输出谁即可
判断是否合法
*/
/*
测试:选取一个随机值(srand(time(0)))
随机插入100以内的数,20次
index如何取到负数
*/
/* 动态开辟内存
malloc:堆区开辟,不清空,返回首地址
calloc:堆区开辟,请空,返回首地址
realloc:对连续空间再次开辟,
会优先尝试在原来的空间上扩容返回原来的,
不行的话会找一个够大的空间,然后把原来的拷贝过来,再释放原来的空间,最后返回新的地址值。
如果发现找不到这样的空间的话,realloc仍让会返回,不过返回的地址是NULL空地址。
注意动态开辟的话如果直接返回到vec->data的话,如果开辟失败会导致原数据永久丢失,数据泄露
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _Vector{
int *data;
int size, length;
}vector;
vector *init(int n){
vector *vec = (vector *)malloc(sizeof(vector *));
vec->data = (int *)malloc(sizeof(int) * n);
vec->size = n;
vec->length = 0;
return vec;
}
int insert(vector *vec, int ind, int val){
if (ind < 0 || ind > vec->length) return 0;
if (vec == NULL) return 0;
for(int i = vec->length; i > ind; i --){
vec->data[i] = vec->data[i - 1];
}
vec->data[ind] = val;
vec->length += 1;
return 1;
}
int erase(vector *vec, int ind){
if (vec == NULL) return 0;
if (ind > vec->length || ind < 0) return 0;
for(int i = ind; i < vec->length; i ++){
vec->data[ind - 1] = vec->data[i];
}
vec->length -= 1;
return 1;
}
int expand(vector *vec){
int extr = vec->size;
int *p;
while(extr){
p = (int *)realloc(vec->data, sizeof(int) * (vec->length + extr));
if (p) break;
extr /= 2;
}
if (!extr) return 0;
vec->data = p;
vec->size += extr;
}
void clear(vector *vec){
free(vec->data);
free (vec);
return;
}
void output(vector *vec){
printf("vector = [");
for(int i = 0; i < vec->length; i ++){
i && printf(" ");
printf("%d", vec->data[i]);
}
printf(" ]\n");
return ;
}
int main(){
srand(time(0));
#define len 100
vector *vec = init(len);
for(int i = 0; i < len; i ++){
int loop = rand() % 4;
int ind = rand() % (vec->length + 3) - 1;
int val = rand() % 100;
switch(loop){
case 0:
case 1:
case 2:{
printf("insert %d at %d to vector ,now :%d\n", val, ind, insert(vec , ind , val));
}break;
case 3:{
printf("erase a num at %d from vector,now :%d\n", ind, erase(vec, ind));
}break;
}
output(vec);
printf("\n");
}
clear(vec);
#undef len
return 0;
}