数据结构-静态链表

静态链表听说是前人为了模仿指针而想出来的,数组本来的下标和游标在程序的对应关系变化着实让人觉得惊叹。

规定:
1、在静态链表中第一个和最后一个元素,它们的data中不存放数据
2、通常将未使用的数组元素称为备用链表
3、数组的一个元素(下标为0的元素)的cur存放备用链表的第一个结点的下标
4、数组的最后一个元素(下标为MAXSIZE-1的元素)的cur存放第一个有数值的元素的下标,相当于单链表的头结点

初始化后静态链表

静态链表需要实现c的malloc和free函数,来进行结点的申请和释放操作

//分配结点函数
int Malloc_SL(SLinkList space)
{
    int i = space[0].cur;//space[0].cur存的都是链表元素下一个紧接的空位置
    if(space[0].cur)
        space[0].cur = space[i].cur;//为space[0].cur存入下一个空结点的数组下标
    return i;
}

//回收结点
void Free_SL(SLinkList space, int k)
{
    space[k].cur = space[0].cur;
    space[0].cur = k;
    //将要删除结点的下标赋值给space[0].cur,后面通过控制输出来实现结点的释放
}

malloc操作

insert操作
插入操作

delete操作
删除操作
这里结点并非真正的销毁了,而是可以说“隐藏”了,仍然可以通过数组下标访问到。

#include "stdio.h"
#include "stdlib.h"
#include "math.h"

#define OK 0
#define ERROR 0
#define MAXSIZE 50

typedef int ElemType;
typedef int Status;

typedef struct
{
    ElemType data;
    int cur; //相当于单链表的指针
} Component, SLinkList[MAXSIZE];

Status visit(ElemType c)
{
    printf("%c ",c);
    return OK;
}

Status ListTraverse(SLinkList space)
{
    int j=0;
    int i=space[MAXSIZE-1].cur;
    while(i)
    {
        visit(space[i].data);
        i=space[i].cur;
        j++;
    }
    return j;
    printf("\n");
    return OK;
}


// 初始化静态链表
Status InitList(SLinkList space)
{
    int i;
    for(i=0; i<MAXSIZE-1; i++)
        //将所有空结点都连接起来
        space[i].cur = i+1;
    space[MAXSIZE-1].cur = 0;
    return OK;
}

//分配结点函数
int Malloc_SL(SLinkList space)
{
    int i = space[0].cur;
    if(space[0].cur)
        space[0].cur = space[i].cur;
    return i;
}

//回收结点
void Free_SL(SLinkList space, int k)
{
    space[k].cur = space[0].cur;
    space[0].cur = k;
    //将要删除结点的下标赋值给space[0].cur,后面通过控制输出来实现结点的释放
}

//静态链表的长度
int ListLength(SLinkList space)
{
//    int i=0,j=0;
//    while(space[i].cur==0) //想着直接判断游标为0就链表就循环完了,谁知连起始点都没找到
//    {
//        i = space[i].cur;
//        ++j;
//    }
    int i= space[MAXSIZE-1].cur;//从头节点开始
    int j=0;
    while(i)
    {
        i=space[i].cur;
        j++;
    }
    return j;
}

//插入新的数据元素e
Status ListInsert(SLinkList space, int i, ElemType e)
{
    int j, k, l;
    k = MAXSIZE - 1; //数组的最后一元素相当于头结点
    if (i < 1 || i > ListLength(space) + 1)
        return ERROR;
    j = Malloc_SL(space);
    if (j)
    {
        space[j].data = e; //插入数据
        //以下操作用于改变游标
        for(l = 1; l <= i - 1; l++)//遍历到要插入元素位置的前一个位置
            k = space[k].cur;
        space[j].cur = space[k].cur;
        space[k].cur = j;
        return OK;
    }
    return ERROR;
}

//删除在L中第i个数据元素
Status ListDelete(SLinkList space, int i)
{
    int j, k;
    if (i < 1 || i > ListLength(space))
        return ERROR;
    k = MAXSIZE - 1;
    for (j = 1; j <= i - 1; j++)//循环至删除位置的前一个元素位置
        k = space[k].cur;
    j = space[k].cur;
    space[k].cur = space[j].cur;//将删除结点与后一结点游标交换
    Free_SL(space, j);
    return OK;
}

int main(void)
{
    SLinkList L;
    Status i;
    i=InitList(L);
    printf("初始化L后:L.length=%d\n",ListLength(L));

    i=ListInsert(L,1,'A');
    i=ListInsert(L,2,'B');
    i=ListInsert(L,3,'D');
    i=ListInsert(L,4,'E');
    i=ListInsert(L,5,'F');


    printf("\n在L的表头依次插入FEDBA后:\nL.data=");
    ListTraverse(L);

    i=ListInsert(L,3,'C');
    printf("\n在L的“B”与“D”之间插入“C”后:\nL.data=");
    ListTraverse(L);

    i=ListDelete(L,1);
    printf("\n在L的删除“A”后:\nL.data=");
    ListTraverse(L);
    printf("\n表长:L.length=%d\n",ListLength(L));

    //A删除之后B为位置1
    i=ListDelete(L,2);
    printf("\n在L的删除“C”后:\nL.data=");
    ListTraverse(L);
    printf("\n表长:L.length=%d\n",ListLength(L));

    printf("\n");

    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值