c语言数据结构-静态链表

 (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

初识静态链表: 

静态链表的插入: 

获得静态链表的长度: 

静态链表的删除: 

四种链表的比较: 


(本章与之前的链表知识有些不同,理解起来可能有些困难(我花了好久才理解),如果看完后有困惑,欢迎私信一起讨论)  

初识静态链表: 

用数组描述的链表,即为静态链表
在c语言中,静态链表的表现形式即为结构体数组
结构体变量包括数据域data和游标next

优点:在插入时只需要修改游标,不需要移动元素 

#define MAX_SIZE_SSL 10
typedef struct
{
	int id;
    char* name;
}ElementType;

/** 静态链表-就是一个结构数组 */
typedef struct {
    ElementType data;       //数据域
    int next;               //int cursor;   游标,如果为0表示无指向
}StaticLinkList[MAX_SIZE_SSL];

初始化:

每个元素的游标指向下一个元素

数组的最后一个元素next用来保存第一个插入元素的下标,最后一个元素初始为0 

第一个元素的next用来存放第一个空闲结点的下标

因此,数组的第一个和最后一个元素不属于数据域范围,所以当倒数第二个元素指向最后一个元素时,实际上指向为0

/** 初始化链表 */
void InitStaticLinkList(StaticLinkList slList)
{
    for (int i = 0; i < MAX_SIZE_SSL; i++)
    {
     
        slList[i].next = i + 1;//游标指向下一个
    }
    //将最后一个结点置空
    slList[MAX_SIZE_SSL - 1].next = 0;
    //将备用链表的尾结点(倒数第二个元素)置为空
    slList[MAX_SIZE_SSL - 2].next = 0;
}

静态链表的插入: 

 第一个元素的next用来存放第一个空闲结点的下标,当数组下标为1的结点插入数据后,第一个元素的next就改为2(即下一个空闲结点的下标),同时将刚插入数据的元素的next改为0(这里有些难以理解,请大家结合图例)

初始化时: 

在数组下标为1的位置插入数据后 :

数据一直插入到下标为4的位置后 :

                                               

/** 向指定位置插入元素 */
int InsertStaticLinkList(StaticLinkList slList, int pos, ElementType element) {
    if (pos < 1 || pos > GetStaticLinkList(slList) + 1) {
        return 0;
    }
    int cursor = MAX_SIZE_SSL - 1;  //拿到第一个元素的下标
    //需要判断cursor的范围是否合法
    //分配内存
    int newIndex = mallocSSL(slList);//待插入结点的下标
    if (newIndex) {
        slList[newIndex].data = element;
        //找到newIndex的前缀结点
        for (int i = 1; i <= pos - 1; i++) {
            cursor = slList[cursor].next;
        }
        slList[newIndex].next = slList[cursor].next;
        slList[cursor].next = newIndex;//使前缀结点的next指向newIndex
        return 1;
    }
    return 0;
}

/** 为静态链表分配一个空间的内存,返回0表示分配失败 */
int mallocSSL(StaticLinkList slList) {
    //拿到第一个空闲结点下标(备用链表)下标
    int cursor = slList[0].next;
    //将该下标改为下一个空闲结点的下标
    if (cursor) {
        slList[0].next = slList[cursor].next;
    }
    return cursor;
}

获得静态链表的长度: 

/** 获得静态链表的长度 */
int GetStaticLinkList(StaticLinkList slList) {
    int count = 0;
    int cursor = slList[MAX_SIZE_SSL - 1].next;
    while (cursor) {
        //p = p->next
        cursor = slList[cursor].next;
        count++;
    }
    return count;
}

静态链表的删除: 

/** 删除链表中指定位置的元素 */
int DeleteStaticLinkList(StaticLinkList slList, int pos) {
    if (pos < 1 || pos > GetStaticLinkList(slList)) {
        return 0;
    }
    int cursor = MAX_SIZE_SSL - 1;
    //通过循环找到要删除位置的前缀结点
    for (int i = 1; i <= pos - 1; i++) {
        cursor = slList[cursor].next;
    }
    int delIndex = slList[cursor].next;
    slList[cursor].next = slList[delIndex].next;
    //释放空间
    FreeStaticLinkList(slList, delIndex);
    return 1;
}

/** 回收原始数组中指定下标的空间 */
void FreeStaticLinkList(StaticLinkList slList, int index) {
    //将下标为index的空闲结点回收到备用链表
    slList[index].next = slList[0].next;
    //0号元素的next结点指向备用链表的第一个结点,表示index结点空闲
    slList[0].next = index;
}

四种链表的比较: 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周不摆烂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值