静态链表的简单实现(C语言)

认识静态链表

静态链表的本质就是结构体数组。结构体中一般有两个结构成员,一个用于存放数据,一个用于存放下一个结点的数组下标(作用类似指针,有人称之为游标(cursor))。
静态数组的具体实现有多种方式,这里我作两个思路分析。
方法一
0号结点作为头结点(head),头结点不存放数据,他的游标存储着第一个存储元素的结点。这种方法插入时需要遍历链表直到第一个未使用的结点。搜索空结点的时间复杂度较大。
在这里插入图片描述

方法二
使用两个不存放数据的结点。一个结点作为头结点(head),游标存储着第一个存储数据的结点的下标。另一个结点备用池(pool),游标存储着第一个空闲空间的下标(该节点一般放在1号结点或最后一个结点)。通过这两个结点,把静态链表变成了一个共享链表。一个存储数据的数据表,以head为头结点;一个存储空闲空间的链表,以pool为头结点。
在这里插入图片描述
方法二的数据存储空间会比第一种方法少一个,但是搜索空闲结点的时间复杂度大大降低。
当数据量较小时可用方法一,数据量大时一定要用方法二。下面代码实现中,我使用了方法二。
静态链表一般用于不支持指针的语言。或元素数量固定不变的场景。

插入

后插创建

// 尾插法一次插入多元素
void CreateList(SLinkList L, int len){
   
    int cur = 0;    // 游标,用于记录next
    ElemType e;
    printf("Please enter %d elements one by one in order!\n", len);
    while(L[cur].next != -1){
       // 遍历至表尾
        cur = L[cur].next;
    }
    while(len--){
   
        scanf("%d", &e);
        if(L[0].next == -1){
       // 如果还没有结点被使用,令头结点指向第一个结点
            L[0].next = 1;
        }
        if(L[pool].next != pool){
           // 申请空间
            L[cur].next = L[pool].next;  // 结点指向新结点
            cur = L[pool].next;
        } 
        L[pool].next++;         // 返回L[pool].next并将
        L[cur].data = e;        // 数据存入
        L[cur].next = -1;       // 声明表尾
    }
}

按位插入

// 按位插入
bool ListInsert(SLinkList L, int pos, ElemType e){
   
    if(L == NULL || pos > MaxSize-2 || pos < 0) return false; // 数据合法性判断
    int cur = 0;                // 游标,用于记录结点下标
    while(--pos){
                  // 定位到插入位置的前继
        cur = L[cur].next;
    }
    int p = L[cur].next;        // p为插入位置的下一结点游标
    if(L[pool].next == pool) return false;  // 空间不足
    L[cur].next = L[pool].next; // 指向第一个备用空间
    int q = L[cur].next;        // q为插入位置的游标
    L[q].data = e;              // 存入数据 
    if(L[cur].next == -1){
         // 如果插入位置在表尾
        L[q].next = -1;
    }else{
   
        L[q].next = p;          // 指向原后继
    }
    return true;
}

删除

按位删除

// 按位删除
bool ListDelete(SLinkList L, int pos){
   
    if(L == NULL || pos > MaxSize-2 || pos < 0) return false; // 数据合法性判断
    int cur = 0;                // 游标,用于记录结点下标 
    while(--pos){
                  // 定位到删除位置的前继
        cur = L[cur].next;
    }
    int p = L[cur].next;        // p为删除位置
    if(L[p]
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值