C语言静态链表

在C语言中用指针可以实现线性单链表,而有些语言不支持指针,我们可以利用两个并行的数组或者结构体数组来模拟指针,这样子的链表称之为静态链表。

在我看来,静态链表的优点就是,虽然没有指针,但通过游标操作,同样实现了指针具有的一些优点,比如插入删除操作不需要像顺序存储结构那样移动很多的元素。

它的缺点就是在不知道需要多少存储空间时,预先分配了一个很大的数组,这样还是比较浪费的。静态链表主要是给没有指针的高级语言设计的,这种思想非常巧妙,值得我们学习。

下面,我给出了C语言下的实现方法,并给出了基本的操作函数,以及针对每种操作,都进行了打印输出的验证。

/*******************************************************************/
//描述:使用结构体数组静态链表的创建,插入,删除等基本操作的函数,以及对这些操作进行验证
//时间:2017.12.29  11:00
//作者:Liu ZhenHua
//*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1000
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0

typedef char ElemType;
typedef int Status;

typedef struct{
    ElemType data;
    int cur;
}Component,StaticLinkList[MAXSIZE];

Status InitList(StaticLinkList space);      //初始化静态链表
int malloc_SLL(StaticLinkList L);           //分配新的空间
int listLength(StaticLinkList sl);          //读取链表长度,即链表存储有几个数据
Status GetElem(StaticLinkList L,int i,ElemType *e);
void printStaticLinkList(StaticLinkList L); //顺序打印链表
                                            //在第i个元素之前插入元素e
Status InsertElem(StaticLinkList L,int i,ElemType e);
                                            //删除掉第i个元素
Status DeleteElem(StaticLinkList L,int i,ElemType *e);
void printSL(void);                         //打印一行分割线
int main()
{
    char cv = 'a';int listlen;
    StaticLinkList sl;
    char tempchar,*cp;cp = &tempchar;
    if(InitList(sl))printf("静态链表创建成功!\n");
    //初始化后生成一个包含4个元素的新链表
    sl[1].data=cv;sl[2].data=cv+1;sl[3].data=cv+2;sl[4].data=cv+3;sl[4].data=cv+3;
    sl[0].cur=5;sl[4].cur=0;sl[MAXSIZE-1].cur=1;
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    printSL();
    if(GetElem(sl,3,cp)){
        printf("取出第三个元素为:%c\n",*cp);
    }else{
        printf("取出元素失败!\n");
    }

    printSL();                      //插入操作
    if(InsertElem(sl,2,'e'))printf("在第二个插入元素'e'之后\n");
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    printSL();                      //删除操作
    if(DeleteElem(sl,3,cp))printf("删除第三个元素成功!\n");
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    return 0;
}
/**********************************************/
//函数名:InitList
//描述  : 初始化静态链表
//参数  :结构体数组space
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status InitList(StaticLinkList space){
    int i;
    for(i=0;i<MAXSIZE-1;i++){
        space[i].cur = i+1;
    }
    space[MAXSIZE-1].cur=0;
    return OK;
}
/**********************************************/
//函数名:malloc_SLL
//描述  : 分配一个新空间,并且第一个元素的下标指向新的未使用空间
//参数  :结构体数组space
//返回值:新的元素的数组下标
//作者  :LiuZhenHua
/**********************************************/
int malloc_SLL(StaticLinkList L){
    int k;
    k = L[0].cur;
    L[0].cur = L[k].cur;   //分配一个新的单位,第一个元素下标依然指向空链表
    return k;              //返回分配的空单位的数组下标,注意数组下标!=元素的下标

}
/**********************************************/
//函数名:listLength
//描述  : 返回静态链表长度
//参数  :结构体数组名
//返回值:链表长度
//作者  :LiuZhenHua
/**********************************************/
int listLength(StaticLinkList sl){
    int k;int i = 0;
    k = MAXSIZE - 1;
    k = sl[k].cur;
    while(k){
        k = sl[k].cur;
        i++;
    }
    return i;
}
/**********************************************/
//函数名: printStaticLinkList
//描述  : 顺序打印链表存储的元素值
//参数  :结构体数组名
//返回值:无
//作者  :LiuZhenHua
/**********************************************/
void printStaticLinkList(StaticLinkList L){
    int k,i,m=0;
    ElemType value;
    k = MAXSIZE - 1;
    i = L[k].cur;
    while(i!=0){
        value = L[i].data;
        printf("链表元素%d: %c\n",++m,value);
        i = L[i].cur;
    }
    printf("链表打印完毕!\n");
}
/**********************************************/
//函数名: InsertElem
//描述  : 在第i个元素前插入元素e
//参数  :结构体数组名
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status InsertElem(StaticLinkList L,int i,ElemType e){
    int j,k,m;
    k = MAXSIZE - 1;
    if(i > MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //插入位置不对或者链表为空链表
    }
    for(j = 0; j < i-1; j++){       //循环,得到插入位置左邻元素的数组下标
        k = L[k].cur;
    }

    m = malloc_SLL(L);              //开辟一个新空间,并返回要插
    L[m].data = e;                  //将数据存入元素的数据域
    L[m].cur = L[k].cur;            //更换元素下标
    L[k].cur = m;
    return OK;
}
/**********************************************/
//函数名: DeleteElem
//描述  : 在第i个元素前删除元素e
//参数  :结构体数组名,位置i,返回元素指针*e
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status DeleteElem(StaticLinkList L,int i,ElemType *e){
    int j,k,n1,n2;
    k = MAXSIZE - 1;
    if(i > MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //删除位置不对或者链表为空链表
    }
    for(j = 0; j < i-1; j++){       //循环,得到插入位置左邻元素的数组下标
        k = L[k].cur;
    }
    n1 = k;
    k = L[k].cur;
    *e = L[k].data;
    n2 = L[k].cur;
    L[n1].cur = n2;
    L[k].cur=L[0].cur;              //交换元素的下标,更换空链表
    L[0].cur=k;
    return OK;
}
/**********************************************/
//函数名: printSL
//描述  : 打印一行分割线Print Split Line
//参数  :结无
//返回值:无
//作者  :LiuZhenHua
/**********************************************/
void printSL(void){
    int i;
    for(i = 0; i < 20; i++){
        printf("-");
    }
    printf("\n");
}
/**********************************************/
//函数名: GetElem
//描述  : 取出在第i个位置的元素e
//参数  :结构体数组名,位置i,返回元素指针*e
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status GetElem(StaticLinkList L,int i,ElemType *e){
     int j,k;
     k = MAXSIZE - 1;                //最后一个元素的数组下标
      if(i > MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //插入位置不对或者链表为空链表
    }
     for(j = 0; j < i; j++){       //循环,得到插入取出元素的数组下标
        k = L[k].cur;
    }
    *e = L[k].data;
    return OK;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nwsuaf_huasir

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

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

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

打赏作者

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

抵扣说明:

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

余额充值