c语言顺序链表基础操作

上课老师说可以建一个基础的代码库来提高编程效率,感觉目前的学习情况,我的代码编写还不足以沿用那么久,所以在此进行一些目前学习的代码的整理以及思考总结,希望以后可以加以改进。仅供参考,若发现任何错误,希望能得到您的指点,感谢观看。

以下是尾插法建立链表的代码

  • 定义一个结构体储存顺序表的各项性质

#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++;
    }
}

线性表的操作类似数组,缺点在于其删除与插入的时间复杂度高。由于其存储特点为物理相邻,删除以及插入都需要移动大量数据以便腾出空间,需要耗费大量时间。

其优点在于可以便于定位,可以随机存取,不需要一一遍历各个节点,与链表各司其职,各有其特性,在不同场景下可以根据需求选择使用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值