顺序表
结构定义
一个数组+2个元素(size数组大小,count数组储存元素个数)
#include <stdio.h>
#include <stdlib.h>
//结构定义
typedef struct vector{
int size;//数组大小
int count;//输出储存元素个数
int *data;//数组本身的指针
}vector;
结构操作
初始化
vector *getNewVector(int n){**//返回的是一个size=n的顺序表**
vector *p=(vector *)malloc(sizeof(vector));**//p是一个指向vector类型的指针,所占的空间大小是vectoor的结构体那么大**
p->size=n;**//大小为n**
p->count=0;**//初始化值为0(起始的时候没有元素)**
p->data=(int *)malloc(sizeof(int)*n);**//p中的data对应分配的大小就是sizeof(int)*n个
}**
销毁
void clear(vector *v){
if (v==NULL)return ;//由于是void函数返回直接是空值
free(v->data);//先释放里面的内存
free(v);//再释放外面的内存
return;
}
插入
选取插入点A,将A后面所有的元素都平移至连续排列,然后将数据放入A位置
int insert(vector *v,int pos,int val){
if(pos<0||**pos>v->count**)return 0;//判断数据合法性
**if(v->size==v->count&&!expand(v))return 0;//扩容也不成功才返回0**
if( v->size==v->count)return 0;//插入超出数组大小,插入不成功返回0
//逆序遍历,顺序遍历会导致数据覆盖问题
for(int i=v->**count-1**;i>=pos;i--){
v->data[i+1]=v->data[i]
}//移位操作
v->data[pos]=val;//插入数据
v->count+=1;//改变元素数
return 1;
}
删除
删除A位置的元素,然后将A后面的元素向前平移至连续排列
int erase(vector *v,int pos){
if(pos<0||pos>**=v->count**)return 0;//判断数据合法性
//逆序无法完成,只能顺序
for (int i=pos+1;i<v->count;i++){
v->data[i-1]=v->data[i];
}//移位操作
v->count-=1;//改变元素数
return 1;
}
自动扩容
插入过程中发现容量满了,再发起扩容
int expand(vector *v) {
if (v == NULL) return 0;//指向空地址无法进行扩容操作
//2倍扩容法,对data区进行扩容--realloc
printf("expand v from %d to %d\\n", v->size, 2 * v->size);
**int *p =** (int *)realloc(v->data, sizeof(int) * 2 * v->size);
**if (p == NULL) return 0;**
v->data = p;
v->size *= 2;
return 1;
}
**realloc的处理逻辑有3种方式
1.原内存后面有内存存在,所以直接在后面进行内存扩容返回原来的地址
2.原内存后面扩容区域不够,于是新开辟一段内存然后再拷贝原来内存的信息到新的内存中去,返回新的地址
3.找不到能达到扩容大小的区域,返回NULL,原内存不动
//此处有bug,会丢失原来存储信息
那么如何处理呢?来一个新的指针被realloc赋值,如何不为空再复制给data(上面绿色部分)**
测试代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct vector {
int size, count;
int *data;
} vector;
vector *getNewVector(int n) {
vector *p = (vector *)malloc(sizeof(vector));
p->size = n;
p->count = 0;
p->data = (int *)malloc(sizeof(int) * n);
return p;
}
int expand(vector *v) {
if (v == NULL) return 0;
printf("expand v from %d to %d\\n", v->size, 2 * v->size);
int *p = (int *)realloc(v->data, sizeof(int) * 2 * v->size);
if (p == NULL) return 0;
v->data = p;
v->size *= 2;
return 1;
}
int insert(vector *v, int pos, int val) {
if (pos < 0 || pos > v->count) return 0;
if (v->size == v->count && !expand(v)) return 0;
for (int i = v->count - 1; i >= pos; i--) {
v->data[i + 1] = v->data[i];
}
v->data[pos] = val;
v->count += 1;
return 1;
}
int erase(vector *v, int pos) {
if (pos < 0 || pos >= v->count) return 0;
for (int i = pos + 1; i < v->count; i++) {
v->data[i - 1] = v->data[i];
}
v->count -= 1;
return 1;
}
void output_vector(vector *v) {
int len = 0;
for (int i = 0; i < v->size; i++) {
len += printf("%3d", i);//记录第一行总长度从而来确定第二行的长度
}
printf("\\n");
for (int i = 0; i < len; i++) printf("-");
printf("\\n");
for (int i = 0; i < v->count; i++) {
printf("%3d", v->data[i]);
}
printf("\\n");
printf("\\n\\n");
return ;
}
void clear(vector *v) {
if (v == NULL) return ;
free(v->data);
free(v);
return ;
}
int main() {
srand(time(0));
#define MAX_OP 20
vector *v = getNewVector(2);//最开始只能加两个元素,但是上界仍然是20
for (int i = 0; i < MAX_OP; i++) {
int op = rand() % 4, pos, val, ret;
switch (op) {
case 0:
case 1:
case 2:
pos = rand() % (v->count + 2);//为了取到可能的非法值,用随机数模取
val = rand() % 100;
ret = insert(v, pos, val);
printf("insert %d at %d to vector = %d\\n",
val, pos, ret);
break;
case 3:
pos = rand() % (v->count + 2);
ret = erase(v, pos);
printf("erase item at %d in vector = %d\\n",
pos, ret);
break;
}
output_vector(v);
}
clear(v);
return 0;
}