目录
五点注意事项:
强制转换
1.注意的是在申请空间的时候,经常需要强制转换,或者是一定需要强制转换,嗯,说的严重一点记得清楚。
空间问题
2.插入的时候需要考虑空间问题,删除的时候不需要,GET的时候同样不需要
考虑空表问题
3.插入的时候不需要考虑空表问题,删除的时候和GET的时候都需要
realloc
4.申请动态内存的函数是realloc。
C++的&L与C语言的*L(看教材时要注意)
5.注意的是在数据结构教材中 Status InsertList(SqList &L,Status i,Status e),这里面的参数是&L,这个在C里面是不允许的,但是在C++里面是可以的,这是引用的意思,但是在C里面是没有引用这个概念的传地址的话,是用指针接着,要注意。
//所以如果是接收参数是&L,那就可以用L.elem,L.length,L.Listlength,因为接收到的是结构体的真实地址,C++里面是有这个引用的。
//如果接收参数是*L,那么就用的是L->elem,L->length,L->listsize,因为接收到的是指向结构体真实地址的指针地址,C语言里面用的是这个
代码如下:
#include<stdio.h>
#include<malloc.h>
//宏定义
#define OK 1
#define ERROR 0
#define LIST_INIT_SIZE 20
#define LISTINCREMENT 10
typedef int Status;
//抽象类型
typedef int Status;
typedef struct {
Status *elem;//基地址
Status length;
Status Listlength;
}SqList;
Status init_list(SqList *L){
L->elem=(Status *)malloc(LIST_INIT_SIZE*sizeof(SqList));//分配空间,并且强制转换
L->length=0;
L->Listlength=LIST_INIT_SIZE;//将申请的初始空间的长度赋给记录线性表长度的变量。
return OK;//返回OK,初始化成功
}
//写插入函数
//参数:*L,i,e;因为我们要对线性表本体进行变动,所以不能传过来副本,只能传过来真实地址来操作。所以L带*号
Status InsertList(SqList *L,Status i,Status e){
//初始条件:L可以是空表但是L的空间不能是满的,插入位置是合适的,不能是负数,0或者大于length+1的数,
if(i<1 || i>L->length+1){
return ERROR;
}
//如果表满了,我们可以进行动态分配,即再申请空间,申请动态内存的函数是realloc。
if(L->length==L->Listlength){
Status* newbase = (Status *)realloc(L->elem,(L->Listlength+LISTINCREMENT)*sizeof(SqList));
if(!newbase){//如果newbase不存在,那么说明申请失败.
printf("申请内存失败");
return ERROR;
}
L->elem=newbase;//将新的地址赋给线性表
L->Listlength=L->Listlength+LISTINCREMENT;//更新线性表长度
}
//走到这里说明现在表既不满,而且插入位置合适
for(Status j=L->length-1;j>=i-1;j--){
L->elem[j+1]=L->elem[j];
}
//此时j应当是等于i-2的即此时j位于线性表要插入位置的前一个位置,那么说明要插入位置已经向后移动了.
//所以即使要插入位置是1即i=1或者插入的位置是线性表最后一个元素的后面即i=L->length+1,也是没有问题的,因为当i=1或者i=L->length+1的时候,不需要元素向后移动.
L->elem[i-1]=e;
L->length++;
return OK;
return OK;
}
//写GetElem函数
//参数:L,i,*e 因为我们不需要改变L,那么不用讲真实L的地址传过来,直接传过来一个副本,但是取出来的数据需要我们回传,即传回主函数中,所以需要加*;
Status GetElem(SqList L,Status i,Status *e){
//初始条件是:L不能为空表或者不存在即没有开辟内存,需要查看的位置是合理的,即1<=i<=L->length
if(!L.elem || L.length==0 || i<1 || i>L.length){
return ERROR;
}
//走到这里说明了都合理那么直接就取就行了,顺序的的查取还是很简单的
*e = L.elem[i-1];
return OK;//可能会疑惑为啥不是传e回去,因为我们传过来的e是真实地址,所以在上一条命令赋值的时候就已经变相的传回去值了.
}
Status main(){
SqList L;
init_list(&L);
InsertList(&L,1,1);//懒
InsertList(&L,2,2);
InsertList(&L,3,3);
InsertList(&L,4,4);
InsertList(&L,5,5);
InsertList(&L,6,2);
InsertList(&L,7,3);
InsertList(&L,8,4);
InsertList(&L,9,5);
InsertList(&L,10,1);
InsertList(&L,11,2);
InsertList(&L,12,3);
InsertList(&L,13,4);
InsertList(&L,14,5);
InsertList(&L,15,1);
InsertList(&L,16,2);
InsertList(&L,17,3);
InsertList(&L,18,4);
InsertList(&L,19,5);
InsertList(&L,20,5);
InsertList(&L,1,1111);
InsertList(&L,1,1111);
InsertList(&L,1,1111);
InsertList(&L,1,1111);
InsertList(&L,1,1111);
Status e;
for(Status k=1;k<=L.length;k++){
GetElem(L,k,&e);
printf("%d\n",e);
}
}
//1.注意的是在申请空间的时候,经常需要强制转换,或者是一定需要强制转换,嗯,说的严重一点记得清楚
//2.插入的时候需要考虑空间问题,删除的时候不需要,GET的时候同样不需要
//3.插入的时候不需要考虑空表问题,删除的时候和GET的时候都需要
//4.申请动态内存的函数是realloc。
//5.注意的是在数据结构教材中 Status InsertList(SqList &L,Status i,Status e),这里面的参数是&L,这个在C里面是不允许的,但是在C++里面是可以的,这是引用的意思,但是在C里面是没有引用这个概念的传地址的话,是用指针接着,要注意。
//所以如果是接收参数是&L,那就可以用L.elem,L.length,L.Listlength,因为接收到的是结构体的真实地址,C++里面是有这个引用的。
//如果接收参数是*L,那么就用的是L->elem,L->length,L->listsize,因为接收到的是指向结构体真实地址的指针地址,C语言里面用的是这个
运行结果如下: