C数据结构 - 静态链表

对于线性链表可用一维数组来进行描述,这种描述方法便于在没有指针类型的高级程序设计语言中使用链表结构,即使用数组描述的链表称为静态链表。由于全局数组是存储在静态区也叫做静态链表。

C语言具有指针能力使其非常容易地操作内存中的地址和数据,对于面向对象的语言虽然不使用指针,但因为启用了对象引用机制,从某种角度也间接实现了指针的某些作用。但对于早期的编程语言,由于没有指针,链表结构等也就无法实现了,怎么办呢?于是,就有了使用数组来代替指针来描述单链表。使用数组描述的链表叫做静态链表(static list),又称为游标实现法。

动态链表

静态链表和动态链表是线性表链式存储的两种不同的表示方式。

  • 在动态链表中,节点的申请和释放分别使用内存申请函数,如C语言的malloc()和free()两个函数实现。所以链表长度没有限制。由于是动态申请内存,所以每个节点的物理地址不连续,要通过指针来顺序访问。
  • 在静态链表中,操作的是数组,不存在像动态链表的节点申请和释放问题,所以需要自己实现这两个函数,才可以做插入和删除操作。静态链表使用类似于数组方法实现,是顺序的存储结构,在物理上是连续的,且需要预先分配地址空间大小,所以静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需要修改指针。

静态链表原理

一个数组的逻辑分为两部分:空闲链表部分和非空闲链表部分,它们通过指针来连接,空闲链表由空闲头节点连接起来,非空闲链表由非空闲头节点连接起来。空闲链表本质上是作为需要管理的内存,当插入节点时,向管理的内存部分申请空间。当删除节点时,向管理的内存部分释放内存。

空闲链表
  • 下标为0的节点是空闲链表的头节点
  • 下标为1的节点是非空闲链表的头节点

首先,让数组的元素由两个数据域组成,data和cursor。即数组的每个下标都对应一个data和一个cursor。数据域data用来存放数据元素,游标cursor相当于单链表中的next指针,存放元素后继在数组中的下标。

/*线性表的静态链表存储结构*/
#define MAXSIZE 1000

typedef struct
{
    ElemType data;//数据域
    int cursor;//游标,为0表示无指向。
} Component, StaticLinkList[MAXSIZE];

StaticLinkList space;

结构体数组中,space[0]作为备用链表的头指针,space[1]作为链表的头指针。


结构体数组

初始化数组状态

  • 对数组第一个和最后一个元素作为特殊元素处理,不存数据。
  • 把未被使用的数组元素称为备用链表
  • 数组第一个元素即下标为0的元素的cursor就存放备用链表的第一个节点的下标
  • 数组最后一个元素的cursor则存放第一个有数值的元素的下标,相当于单链表中的头节点作用。
  • 当整个链表为空时则为O^2
image.png
游标实现法
线性表的静态链表
/**
 * 将一维数组space中各分量链成一备用链表
 * space[0].cursor 为头指针,0表示空指针。
 */
Status InitList(StaticLinkList space)
{
    int i;
    for(i=0; i<MAXSIZE; i++){
        space[i].cursor = i+1;
    }
    //静态链表为空,最后一个元素的游标为0
    space[MAXSIZE-1].cursor = 0;
    return OK;
}

假设已经将数据存入静态链表,比如分别存放甲乙丙丁午己庚等数据。


静态链表
存放数据

静态链表的插入操作

静态链表如何模拟单链表进行插入和删除操作呢?静态链表要解决的是:如何用静态链表模拟动态链表结构的存储空间分配,也就是需要的时候申请,不需要的时候释放。

为了辨明数组中那些分量未被使用,解决的办法是将所有未被使用过的及已被删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上取得第一个节点作为待插入的新节点。

静态链表的插入

静态链表的插入

获得空闲分量的下标

/**
 * 辨明数组中那些分量未被使用,解决的办法是将所有未被使用多的及已被删除的分量用游标链成一个备用的链表。
 * 每当进行插入时,便可以从备用链表上取得第一个节点作为待插入的新节点。
 */
int MallocSLL(StaticLinkList space)
{
    int i = space[0].cursor;//当前数组第一个元素的游标,即第一个备用空闲的下标。
    //若备用空间链表非空则返回分配的节点的下标否则返回0
    if(space[0].cursor){
        //将下一个分量用来做备用
        space[0].cursor = space[i].cursor;
    }
    return i;
}

在静态链表某个元素之前插入新元素

Status InsertSLL(StaticLinkList L, int i, ElemType e)
{   
    int j,k,l;
    //边界检查
    if(i<1 || i>ListLength(L)+1){
        return ERROR;
    }
    //获得空闲分量的下标
    int j = MallocSSL(L);
    if(j){
        //将数据赋值给此分量的数据域
        L[j].data = e;
        //找到第i个元素之前的位置
        k = MAXSIZE - 1;//最后一个元素
        for(l=1; l<=i-1; l++){
            k = L[k].cursor;
        }
        //将第i个元素之前的游标值赋值给新元素的游标
        L[j].cursor = L[k].cursor;
        //将新元素的下标赋值给地i个元素之前的元素的游标
        L[k].cursor = j;
        return OK;
    }
}

静态链表的删除操作

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容