静态链表的通俗讲解与基本操作(C语言)

静态链表是数据结构线性表中的一种,因为其每一个结点只有一个直接前驱和直接后继,对于开头结点和末尾结点只有一个直接前驱或直接后继。
本人听老师讲课,看老师关于静态链表PPT时有些许不懂,看了CSDN其他关于静态链表的帖子后也还存在许多疑惑,现在自己明白之后试着把它的逻辑写出来。

我们说链表是一种链式存储结构,是因为它每一个结构体节点中存放着下一个结构体节点的地址,通过指针与地址使得链表被称作链。那么在一些语言中,因为封装较完备,我们无法对地址直接进行操作,例如java。所以静态链表可以在某种意义上替代链表。

我们知道但凡一种语言,可能没有指针,但是数组这种基本的数据类型一定会有,静态链表就是利用数组来模拟实现链表的功能。

静态链表有两种形式,第一种是以结构体为基本单元,一个结构体对应一个节点,结构体中有两个元素,一个是该节点存放的数据data,另一个是该节点存放的游标cur(注意cur中存放的是下一个节点的下标,等同于链表中的指针域,都是表示下一个节点的位置信息的);一种是构建两个同步的数组,一个数组存放data,一个数组同步存放该下标对应的cur。其实这俩差不多,第一种更加好理解一点,我们用第一种来举例:

其实我们能将静态链表这一个数组拆成两个链表来看,因为一开始创建数组没有元素存储,所以一开始待存储链表很长,已存储链表为空。我们需要存储数据的时候,就把带存储链表的第一个节点取下,用来存放数据,并把它接到已存储链表上,这样带存储链表越来越短,已存储链表越来越长。

基本思路是:第一个节点(下标index=0)的data不存放数据,cur存放待存储链表的第一个节点下标(注意,是还没有利用过的节点下标)最后一个节点的(下标为length-1)的data不存放数据,cur存放已存储链表的第一个节点的下标。


如图可看大概存储原理↑
下面展示具体代码:

构建静态链表

struct L
{
    int data;
    int cur;
}arr[100];//创建一百个节点大小的静态链表,并定义标签为L的结构体数据类型
#include<stdio.h>
struct L* initlist(struct L* arr,int n)//返回这个结构体数组的首地址
{
    for(int i=1;i<99;i++)
    {
        arr[i].cur=i+1;
    }
    arr[0].cur=2;
    arr[99].cur=1;
    arr[1].data=n;
    arr[1].cur=0;
    return arr;
}

插入操作

插入操作涉及到几部
第一,一定会更改arr[0].cur的值,因为待存储数组的首元素被拿来存储数据,所以值会变更。
第二,可能会更改最后一个节点的cur值(即arr[99].cur),如果插入的元素存储在链表的第一个位置,则会更改。
第三,a->b –> a->c->b,更改指针指向,需要两步操作

struct L* listInsert(struct L* arr,int n,int i)
{
    if(i<=0)
    {
        printf("错误");
        return arr;
    }
    int k=99;
    for(int j=1;j<=i-1;j++)
    {
        k=arr[k].cur;
        if(arr[k].cur==0)
        {
            break;
        }
    }
    int temp=arr[0].cur;
    arr[0].cur=arr[temp].cur;
    arr[temp].data=n;
    arr[temp].cur=arr[k].cur;
    arr[k].cur=temp;
    return arr;
}

删除元素

struct L* listDelete(struct L* arr,int i)
{
    if(i<=0)
    {
        printf("错误");
        return arr;
    }
    int k=99;
    for(int j=1;j<=i-1;j++)
    {
        k=arr[k].cur;
        if(arr[k].cur==0)
        {
            printf("错误");
            return arr;
        }
    }
    int j=arr[k].cur;
    arr[k].cur=arr[j].cur;
    arr[j].cur=arr[0].cur;
    arr[0].cur=j;
    return arr;
}

就这么多吧