上课老师说可以建一个基础的代码库来提高编程效率,感觉目前的学习情况,我的代码编写还不足以沿用那么久,所以在此进行一些目前学习的代码的整理以及思考总结,希望以后可以加以改进。仅供参考,若发现任何错误,希望能得到您的指点,感谢观看。
以下是尾插法建立链表的代码
-
定义一个结构体储存顺序表的各项性质
#define list_init_size 100
#define listincrement 10
typedef struct{
ElemType *elem; //存储空间基址
int length; //线性表当前长度
int listsize; //线性表当前存储容量(以sizeof(ElemType)为单位)
}SqList;
-
初始化顺序表,利用引用来修改顺序表内各项数据
Status InitList(SqList &L){
//构建一个空的线性表(线性表初始化)
L.elem=(ElemType*)malloc(listinitsize*sizeof(ElemType)); //分配首地址所在位置空间
if(!L.elem)
exit(OVERFLOW); //存储空间分配失败
L.length=0; //初始表长度为0
L.listsize=listinitsize; //目前表空间为初始存储容量
return OK;
}
-
顺序表插入数据
Status ListInsert(SqList &L,int i,ElemType e){
if(i<1 || i>L.length+1) //i值不合法
return ERROR;
if(L.length>=L.listsize){ //表空间不足,需要重新分配空间
newbase=(ElemType*)realloc((L.listsize+listcrement)*sizeof(ElemType));
if(!newbase) //存储空间不足,分配失败
exit(OVERFLOW);
L.elem=newbase; //新基址赋值
L.listsize=L.listsize+listcrement; //新的存储容量赋值
}
for(int j=L.length-1;j>=i;j--){ //i-1位置后的数均向后移动腾出空间
L.elem[j+1]=L.elem[j];
}
L.elem[i]=e; //插入数据
++L.length; //表变长
return OK;
}
-
给出元素位置,顺序表删除
数据
Status DeleteList(SqList &L,int i,ElemType &e){
if(i<0 || i>L.length) //依旧是判断i合法
return ERROR;
p=&(L.elem[i-1]); //p取被删除元素的地址值
e=*p; //将被删除元素值赋值给e
q=L.elem+L.length-1;
for(++p;p<=q;++p){
*(p-1)=*p;
} //被删除元素位置后面的值左移
--L.length; //表长度减一
return OK;
}
-
给出元素值,顺序表删除数据
需要寻找元素值所在位置,定义一个定位函数
int LocateElem(SqList &L,ElemType e,Status(*compare(ElemType,ElemType))//传的是指针函数,具体应用详情请移步其他文章
{
i=1;
p=L.elem;
while(i<=L.length-1 && (compare*)(e,*p++)) //对比e的值与p指向的元素值是否相等
++i;
if(i<=L.length) //若未超出表长度,则说明找到所在位置
return i;
else return 0;
}
-
给出元素值,删除数据
Status DeleteList2(SqList &L,int i,ElemType &e){ //唯一不同在于i的值传入的是上述函数的返回值i
if(i<0 || i>L.length) //i合法
return ERROR;
p=&(L.elem[i-1]); //p取被删除元素的地址值
e=*p; //将被删除元素值赋值给e
q=L.elem+L.length-1;
for(++p;p<=q;++p){
*(p-1)=*p;
} //被删除元素位置后面的值左移
--L.length; //表长度减一
return OK;
}
-
顺序表的合并
已知顺序表La和Lb的元素按值非递减排列,归并La和Lb得到新的顺序表Lc,Lc的元素也按值非递减排列
Status MergeList(SqList La,SqList Lb,SqList &Lc){
pa=La.elem;pb=Lb.elem; //pa为顺序表La基地址,pb为顺序表Lb基地址
Lc.listsize=La.length+Lb.length //Lc链表空间容量为La与Lb长度之和
pc=Lc.elem=(ElemType*)malloc(Lc.listsize*sizeof(ElemType));
if(!Lc.elem)exit(OVERFLOW);
pa_last=pa+La.length;
pb_last=pb+Lb.length; //定义尾地址pb_last
while(pa<=pa_last && pb<=pb_last){
if(*pa<=*pb){
*pc=*pa++; //逐个分别取出表LaLb中的值并且一一比较,较小的放入顺序表Lc中
}else{
*pc=*pb++;
}
}
while(pa<=pa_last){ //其中一个表内元素全部取出后,判断哪个表中仍有剩余,并且将其一一放入Lc
*pc=*pa++;
}
while(pb<=pb_last){
*pc=*pb++;
}
}
线性表的操作类似数组,缺点在于其删除与插入的时间复杂度高。由于其存储特点为物理相邻,删除以及插入都需要移动大量数据以便腾出空间,需要耗费大量时间。
其优点在于可以便于定位,可以随机存取,不需要一一遍历各个节点,与链表各司其职,各有其特性,在不同场景下可以根据需求选择使用。