静态链表基础

静态链表的结构设计

typedef struct SNode
{
        int data;//数据

        int next;//后继指针(下标)

}SNode,SLinkList[MAXSIZE];

关于静态链表的结构定义中,SLinkList[MAXSIZE]在这个哔站视频上有解释,不理解的可以去看看https://www.bilibili.com/video/BV1U3411T7D4/?spm_id_from=333.337.search-card.all.click&vd_source=dfc7d849ca4984f3b7805f6425b615eb

静态链表的结构示意图

 

0:有效数据链的头节点;

1:空闲数据链的头节点;

注:我们所有有有效数据的静态链表放入0号头结点,空闲的放入1号头结点

静态链表的实现

//初始化
void InitList(SNode* ps)
{
    assert(ps != NULL);
    if (ps == NULL)
        return;
    //处理有效链表
    ps[0].next = 0;
    //处理空闲链表
    for (int i = 1; i < MAXSIZE; i++)
    {
        ps[i].next = i + 1;
    }
    ps[MAXSIZE - 1].next = 1;//1是空闲链表的表头
}


static   bool IsFull(SNode* ps)
{
    return ps[1].next == 1;
}


//头插
bool Insert_head(SNode* ps, int val)
{
    if (IsFull(ps))
    {
        return false;
    }

    //获取一个空闲节点
    int p = ps[1].next;
    //将空闲节点从空闲链表中剔除
    ps[1].next = ps[p].next;
    //放入数据
    ps[p].data = val;
    //将空闲节点插入到有效链表中
    ps[p].next = ps[0].next;
    ps[0].next = p;

    return true;
}

//尾插
bool Insert_tail(SNode* ps, int val)
{
    if (IsFull(ps))
    {
        return false;
    }

    //获取一个空闲节点
    int p = ps[1].next;
    //将空闲节点从空闲链表中剔除
    ps[1].next = ps[p].next;
    //放入数据
    ps[p].data = val;

    //找尾巴
    int q;
    for (q = 0; ps[q].next != 0; q = ps[q].next)
    {
        ;
    }
    //将节点插入到有效链表中,p插入到q的后面
    ps[p].next = ps[q].next;
    ps[q].next = p;

    return true;
}

//判空
bool IsEmpty(SNode* ps)
{
    return ps[0].next == 0;//有效数据链表没有数据节点
}

//获取数据节点的个数
int GetLength(SNode* ps)
{
    assert(ps != NULL);
    if (ps == NULL)
        return -1;

    int count = 0;
    //遍历有效链表
    for (int p = ps[0].next; p != 0; p = ps[p].next)
    {
        count++;
    }
    return count;
}

//在ps中查找第一个key值,找到返回节点下标,没有找到返回-1;
int  Search(SNode* ps, int key)
{
    assert(ps != NULL);
    if (ps == NULL)
        return -1;

    //遍历有效链表
    for (int p = ps[0].next; p != 0; p = ps[p].next)
    {
        if (ps[p].data == key)
        {
            return p;
        }
    }

    return -1;
}

int  GetPrio(SNode* ps, int key)
{
    for (int p = 0; ps[p].next != 0; p = ps[p].next)
    {
        //if (ps[ps[p].next].data == key)//ok
        int q = ps[p].next;//q为p的后继
        if(ps[q].data==key)
        {
            return p;
        }
    }
    return -1;
}


//删除第一个val的值
bool DelVal(SNode* ps, int val)
{
    //获取val的前驱
    int p = GetPrio(ps, val);
    if (p < 0)
        return false;

    //将节点从有效数据链表中剔除
    int q = ps[p].next;
    ps[p].next = ps[q].next;

    //将节点添加到空闲链表中
    ps[q].next = ps[1].next;
    ps[1].next = q;

    return true;
}

//输出
void Show(SNode* ps)
{
    assert(ps != NULL);
    if (ps == NULL)
        return;
    for (int p = ps[0].next; p != 0; p = ps[p].next)
    {
        printf("%d  ", ps[p].data);
    }
    printf("\n");
}

//清空数据
void Clear(SNode* ps)
{
    assert(ps != NULL);
    if (ps == NULL)
        return;
    InitList(ps);
}

//销毁整个内存
void Destroy(SNode* ps)
{
    Clear(ps);
}

静态链表的总结

1.静态链表,利用顺序表模拟链表
2.静态链表包含两条链表,一条为有效数据链表,另一条为空闲节点链表
3.有效数据链表为带头结点的循环链表,且头节点在0号下标
4.空闲数据链表为带头结点的循环链表,且头节点在1号下标
5.静态链表的优点:和顺序表对比,插入删除不需要移动数据,O(1)
6.静态链表的优点:和链表对比,不需要频繁的创建和删除节点

7.静态链表的缺点:和顺序表对比,需要增加一个next
8.静态链表可以动态增长,满后扩容,将扩容的内存添加到空闲链表;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值