1.顺序表的组成。
1.静态顺序表(固定的元素大小)
静态顺序表的组成如下图代码所示,由一个数组和其大小组成。数组长度固定,size是有效位数。
typedef struct cl{
int arr[10];
int size;
}cl;
2.动态顺序表(元素随时可以增加)
动态顺序表的组成代码由下图:
typedef struct cl{
int *a;
int size;
int capcity;
}cl;
typedef将 struct cl类型重命名为cl,以后初始化结构体只用写cl即可,不用写struct cl cl。这里使用指针可以继续增加空间容量。size存放目前拥有的数据的大小,capcity存放整个数据的大小。
2.顺序表的操作
1.尾插(在数据尾部插入数字)
typedef struct cl{
int *a;
int size;
int capcity;
}cl;
void pushback(cl*p,int x)
{
if((p->size)<(p->capcity));
{
p->a[p->size]=x;//目前由size个元素,直接插入在size后面的个数,就直接尾部插入。
++p->size;//size发生改变
}
if(p->size==p->capcity)
{
int newcapcity=p->capcity==0?4:2*p->capcity;//如果capcity等于0是成立的,那么其被赋值为4,
//不然就返回2*newcapcity,此方法是为了避免capcity=0;
int *s=(int *)realloc(p->a,newcapcity*sizeof(int));//一般扩容是扩大二倍
if(s==NULL)//为了避免realloc开辟失败
{
perror("realloc fail");
exit(1);
}
else{
p->a=s;
}
p->capcity=newcapcity;
}
}
int main()
{
cl s1={NULL,0,0};
pushback(&s1,s1.size);
}
尾插代码比较复杂,详细解释如下:
对于尾插操作我们首先应该判断的是是否还有足够的空间给我们进行插入,那么就应该判断size和capcity到底谁大谁小了,所以在函数中我们先进行两次if判断如下:
1.如果空间足够那么直接插入即可:
目前有size个元素,那么数组存储到size-1,直接另p->a[p->size]=x;再让size++一下。
2.如果空间不够用,此种情况比较复杂:
需要先使用realloc函数进行扩容,再进行插入。我们扩容时一般是扩容原本大小的二倍,所以应该返回2*capcity,但是有capcity是0的情况的可能,所以我们先写一个多目操作符。
int newcapcity=p->capcity==0?4:2*p->capcity;意思是先判断capcity是不是0,如果是就返回4,如果不是返回2*capcity,最后再用newcapcity和realloc函数来开辟空间。
但是使用realloc有可能会开辟失败,所以我们要判断用来接受的新指针s是否为空指针,如果是的话直接打印错误,退出程序,如果不是就重复上述操作。
2.头插
1.顾名思义是再顺序表头部插入一个数字。代码如下
typedef struct cl{
int *a;
int size;
int capcity;
}cl;
void checkcapcity(cl *p)
{
if(p->size>=p->capcity)
{
int newcapcity=p->capcity==0?4:2*p->capcity;//如果capcity等于0是成立的,那么其被赋值为4,
//不然就返回2*newcapcity,此方法是为了避免capcity=0;
int *s=(int *)realloc(p->a,newcapcity*sizeof(int));//一般扩容是扩大二倍
}
}
void pushforward(cl *p,int k)
{
checkcapcity(p);//直接调用函数就ok
for(int i=p->size;i<0;i--){
p->a[i]=p->a[i-1];//将所有数据右移一位
}
p->a[0]=k;
p->size++;
}
//void pushback(cl*p,int x)
//{
// if((p->size)<(p->capcity));
// {
// p->a[p->size]=x;//目前由size个元素,直接插入在size后面的个数,就直接尾部插入。
// ++p->size;//size发生改变
// }
// if(p->size==p->capcity)
// {
// int newcapcity=p->capcity==0?4:2*p->capcity;//如果capcity等于0是成立的,那么其被赋值为4,
// //不然就返回2*newcapcity,此方法是为了避免capcity=0;
// int *s=(int *)realloc(p->a,newcapcity*sizeof(int));//一般扩容是扩大二倍
// if(s==NULL)//为了避免realloc开辟失败
// {
// perror("realloc fail");
// exit(1);
// }
// else{
// p->a=s;
// }
// p->capcity=newcapcity;
// }
//
//}
int main()
{
cl s1={NULL,0,0};
pushback(&s1,s1.size);
}
主要看pushfoward的部分,将上述检查capcity是否足够大和capcity是否为0的操作封装为一个函数,直接调用,再将a中每个元素右移一位,最后将元素插入p->a[0]的位置。
pushback部分已经屏蔽。
标签:newcapcity,顺序,cl,int,realloc,capcity,数据结构,size From: https://blog.csdn.net/2401_86499491/article/details/144197876