代码位置
线性表(linearlist)是n个具有相同特性的数据元素的有限序列。线性表是⼀种在实际中⼴泛使⽤的 数据结构,常见的线性表:顺序表、链表、栈、队列、字符串······
线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的,线性 表在物理上存储时,通常以数组和链式结构的形式存储。
概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。
顺序表和数组的区别?
顺序表的底层结构是数组,对数组的封装,实现了常⽤的增删改查等接⼝。可以这么理解,我们使用数组来存储数据,并提供了增删查改数据的接口(函数),这样组织和存储数据的结构我们将它称为顺序表。
概念:使用定长数组存储元素
概念:不存储数组,而是存储一个指向一块动态开辟的内存空间的指针
优点:按需开辟,可增容
故我们一般都使用动态顺序表
创建顺序表,并将其中的指针置为NULL,容量和有效数据个数置为0,销毁大致相同,不过如果arr指针非空,不要忘了释放动态申请的空间
SeqList.h(其中方法会一一讲到)
#pragmaonce#include #include #include typedefintsldatatype;typedefstructSeqlist{ sldatatype*arr;sldatatype size;sldatatype capacity;}sl;voidslinit(sl*);//初始化voidsldestroy(sl*);//销毁voidslprint(sl*);//打印voidcheckcapacity(sl*);//判断空间是否足够voidslpushback(sl*,sldatatype);//尾插voidslpushfront(sl*,sldatatype);//头插voidslpopfront(sl*);//头删voidslpopback(sl*);//尾删//在指定位置插入和删除数据voidslinsert(sl*,sldatatype,int);voidslfrase(sl*,int);//查找指定数据intslfind(sl*,sldatatype);
test.c
最好是写一个方法测试一次,不然找错误的时候会很痛苦😜
sl s;//要改变s结构体之中的内容,别忘了传地址#define_CRT_SECURE_NO_WARNINGS1#include"Seqlist.h"voidsltest1(){ sl s;slinit(&s);slpushback(&s,1);slpushback(&s,2);slpushback(&s,6);slpushback(&s,5);intm=slfind(&s,7);printf("%d\n",m);//slpushfront(&s, 2);//slpushfront(&s, 3);//slinsert(&s, 1, 0);//slinsert(&s, 2, 6);//slinsert(&s, 1,0 );//slfrase(&s, 1);//slfrase(&s, 0);//slfrase(&s, 1);//slpopback(&s);//slpopback(&s);//slpopback(&s);//slpopback(&s);//slpopback(&s);slpushback(NULL, 6);//slpopfront(&s);//slpopfront(&s);//slpopfront(&s);//slpopfront(&s);//slpopfront(&s);//slpopfront(&s);slprint(&s);sldestroy(&s);}intmain(){ sltest1();return0;}
SeqList.c
函数方法的实现,重点重点!!!
在每一个方法的第一排都使用assert宏来判断ps是否为空(避免使用时传入空指针,后续解引用都会报错)
voidslinit(sl*ps){ assert(ps);ps->arr =NULL;ps->capacity =ps->size =0;}voidsldestroy(sl*ps){ assert(ps);if(ps->arr){ free(ps->arr);ps->arr =NULL;}ps->capacity =ps->size =0;}
考虑到每次测试方法时调试会很麻烦,于是先写一个打印顺序表的方法
voidslprint(sl*ps){ assert(ps);inti =0;for(i =0;i <ps->size;i++){ printf("%d ",ps->arr[i]);}}
插入数据的时候一定要判断空间是否足够,不足要增容,一般2倍或3倍增容!!!
SeqList.c
养成好习惯,不要用arr直接接收动态开辟空间的地址,否则开辟失败arr变为NULL,连原来的内存块都找不到了,这就造成了内存泄漏!!!
voidslcheckcapacity(sl*ps){ assert(ps);if(ps->capacity ==ps->size){ //增容//若capacity为0,给个默认值,否则乘以2intnewcapacity =ps->capacity ==0?4:2*ps->capacity;sldatatype*tmp =(sldatatype*)realloc(ps->arr,newcapacity *sizeof(sldatatype));if(tmp ==NULL){ perror("realloc fail!");exit(1);}ps->arr =tmp;ps->capacity =newcapacity;}}
SeqList.c
voidslpushback(sl*ps,sldatatype x){ assert(ps);slcheckcapacity(ps);ps->arr[ps->size++]=x;}
SeqList.c
voidslpushfront(sl*ps,sldatatype x){ assert(ps);slcheckcapacity(ps);for(inti=ps->size;i>0;i--){ ps->arr[i]=ps->arr[i -1];}ps->arr[0]=x;ps->size++;}
先让每个数据往后一位,注意一定要从后往前挪,否则数据会被覆盖
记得size++
SeqList.c
voidslinsert(sl*ps,sldatatype x,intpos){ assert(ps);assert(pos >=0&&pos <=ps->size);slcheckcapacity(ps);for(inti =ps->size;i >pos;i--){ ps->arr[i]=ps->arr[i -1];}ps->arr[pos]=x;ps->size++;}
删除数据的时候一定要判断顺序表是否为空,即size不能为0!!!
SeqList.c
voidslpopback(sl*ps){ assert(ps &&ps->size);ps->size--;//ps->arr[ps->size] = 0;多余了,没有必要}
SeqList.c
voidslpopfront(sl*ps){ assert(ps &&ps->size);for(inti =0;i <ps->size-1;i++){ ps->arr[i]=ps->arr[i +1];}ps->size--;}
SeqList.c
voidslfrase(sl*ps,intpos){ assert(ps);assert(pos >=0&&pos <ps->size);//包含了顺序表不为空的限定条件for(inti =pos;i <ps->size-1;i++){ ps->arr[i]=ps->arr[i +1];}ps->size--;}
SeqList.c
intslfind(sl*ps,sldatatype x){ assert(ps);inti =0;intflag =0;for(i =0;i <ps->size;i++){ if(ps->arr[i]==x){ flag =1;break;}}if(flag)return1;else{ return-1;}}
SeqList.c(完整版)
#include"Seqlist.h"voidslinit(sl*ps){ ps->arr =NULL;ps->capacity =ps->size =0;}voidsldestroy(sl*ps){ assert(ps);if(ps->arr){ free(ps->arr);ps->arr =NULL;}ps->capacity =ps->size =0;}voidslprint(sl*ps){ assert(ps);inti =0;for(i =0;i <ps->size;i++){ printf("%d ",ps->arr[i]);}}voidslcheckcapacity(sl*ps){ assert(ps);if(ps->capacity ==ps->size){ //增容//若capacity为0,给个默认值,否者乘以2intnewcapacity =ps->capacity ==0?4:2*ps->capacity;sldatatype*tmp =(sldatatype*)realloc(ps->arr,newcapacity *sizeof(sldatatype));if(tmp ==NULL){ perror("realloc fail!");exit(1);}ps->arr =tmp;ps->capacity =newcapacity;}}voidslpushback(sl*ps,sldatatype x){ assert(ps);slcheckcapacity(ps);ps->arr[ps->size++]=x;}voidslpushfront(sl*ps,sldatatype x){ assert(ps);slcheckcapacity(ps);for(inti=ps->size;i>0;i--){ ps->arr[i]=ps->arr[i -1];}ps->arr[0]=x;ps->size++;}voidslpopback(sl*ps){ assert(ps &&ps->size);ps->size--;//ps->arr[ps->size] = 0;多余了,没有必要}voidslpopfront(sl*ps){ assert(ps &&ps->size);for(inti =0;i <ps->size-1;i++){ ps->arr[i]=ps->arr[i +1];}ps->size--;}voidslinsert(sl*ps,sldatatype x,intpos){ assert(ps);assert(pos >=0&&pos <=ps->size);slcheckcapacity(ps);for(inti =ps->size;i >pos;i--){ ps->arr[i]=ps->arr[i -1];}ps->arr[pos]=x;ps->size++;}voidslfrase(sl*ps,intpos){ assert(ps);assert(pos >=0&&pos <ps->size);//还有更多的限制如顺序表不能为空for(inti =pos;i <ps->size-1;i++){ ps->arr[i]=ps->arr[i +1];}}intslfind(sl*ps,sldatatype x){ assert(ps);inti =0;intflag =0;for(i =0;i <ps->size;i++){ if(ps->arr[i]==x){ flag =1;break;}}if(flag)return1;else{ return-1;}}
以上就是顺序表的实现方法啦,各位大佬有什么问题欢饮在评论区指正,您的支持是我创作的最大动力!❤️