美文网首页程序员数据结构和算法分析
【数据结构】线性表之静态链表

【数据结构】线性表之静态链表

作者: NotFunGuy | 来源:发表于2017-07-18 15:17 被阅读705次

网易云课堂小甲鱼课程链接:数据结构与算法

一、什么是静态链表

C语言的伟大,在于指针的灵活性,使得它可以非常容易的操作内存中的地址和数据,这比其他高级语言更加灵活方便。(面向对象使用对象引用机制间接地实现了指针的某些功能)

但是在没有指针的时候,用数组代替指针来描述单链表。
定义:用数组描述的链表叫做静态链表,这种描述方法叫做游标实现法

静态链表
代码实现:
#include <stdio.h>

#define MAXSIZE 1000

typedef int  ElemType; /*  定义数据元素类型,类型名为ElemType,此处所定义的数据元素只包含一个int型的数据项*/
typedef struct {
    
    ElemType data; // 数据
    int cur;      // 游标(Cursor)
    
}Component, StaticLinkList[MAXSIZE];

特点

  • 静态链表中,每一个结点包含两个部分:data(数据)和cur(存储该元素下一个元素所在数组中对应的下标)
  • 下标为0的结点不包含任何数据:如图中,下标为0的结点它的cur存储的是备用链表(即没有存储数据的那些结点,图中下标5后面的结点)。
  • 数组的最后一个元素的cur存放第一个元素的下标:如图中最后一个元素的cur是1,存放的是静态链表的第一个结点的下标,注意此处的第一个结点,是指有实质意义的数据的结点,如图中的数据A存放在下标为1的结点,那么1就是第一个结点。
  • 链表的最后一个元素存cur存放0:链表的最后一个元素,并不一定是数组的最后一个元素(如图中下标为4的元素),它的cur一般是存放0,表示它后面的结点为空了。

对静态链表进行初始化

对静态链表进行初始化相当于初始化数组操作

// 1.对静态链表进行初始化  - 相当于初始化数组
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;
}

获得链表的长度

// 获得链表的长度
int ListLength(StaticLinkList L){
    
    int j = 0;
    int i = L[MAXSIZE-1].cur;
    
    while (i) {
        i = L[i].cur;
        j++;
    }
    
    return j;
}

二、静态链表的插入操作

在动态链表中,结点的申请和释放分别借用C语言的malloc()free()函数来实现。
在静态链表中,操作的是数组,不存在动态链表的节点申请和释放的问题,所以需要自己实现这两个函数,才可以做到插入和删除操作。
为了辨明数组中哪些分量未被使用,解决办法是将所有未被使用的以及已被删除的分量用游标链成一个备用的链表。

在上图的A后面插入一个B的的方式如图:


代码实现:

// 2.静态链表的插入操作

// 2.1获取空闲分量的下标
int Malloc_SLL(StaticLinkList space){
    
    int i = space[0].cur;
    
    if (space[0].cur)
        
        space[0].cur = space[i].cur;
    
    return i;
}

// 2.2在静态链表L中第i个元素之前插入新的数据元素e
Status ListInsert(StaticLinkList L, int i, ElemType e){
    
    int j,k,l;
    
    k = MAXSIZE - 1; // 数组的最后一个元素
    
    if (i<1 || i>ListLength(L)+1) return ERROR;
    
    j = Malloc_SLL(L); // 得到备用链表的第一个元素
    
    if (j) {  // 如果元素存在
        
        L[j].data = e;
        
        for (l = 1; l<=i-1; l++) {  // 得到i-1个元素的下标
            k = L[k].cur;
        }
        
        L[j].cur = L[k].cur; // 将第i-1个元素的cur设置为新加的这个结点的下标,将新加的这个结点的下标设置为之前第i-1个元素存储的cur值
        L[k].cur = j;
        
        return OK;
    }
    
    return ERROR;
    
}

静态链表的插入需要分两步,先是获取空闲的分量,在进行插入操作。

三、静态链表的删除操作

删除的元素要放到备用链表里面

代码实现:

// 3.静态链表的删除操作

// 3.1删除在L中的第i个元素
Status ListDelete(StaticLinkList L, int i){
    
    int j, k;
    
    if (i<1 || i>ListLength(L)) return ERROR;
    
    k = MAXSIZE-1;
    
    for (j = 1; j<= i-1; j++)
        
        k = L[k].cur;
    
    j = L[k].cur;
    L[k].cur = L[j].cur;
    
    Free_SLL(L, j);
    
    return OK;
    
}

// 3.2将下标为k的空闲结点回收到备用链表
void Free_SLL(StaticLinkList space, int k){
    
    space[k].cur = space[0].cur;
    space[0].cur = k;
}

静态链表的优缺点

优点:
  • 在插入和删除操作时,只需要修改游标,不需要移动元素,从而改进了在顺序存储结构中的插入和删除操作需要移动大量元素的缺点。
缺点:
  • 没有解决连续存储分配(数组)带来的表长难以确定的问题。
  • 失去了顺序存储结构随机存取的特性。

相关文章

  • PHP 实现数据结构

    参考诸多视频和文章,主要通过PHP 实现线性表的顺序存储结构,单链表,静态链表,双向链表以及二叉树等数据结构,代码...

  • 数据结构探险之线性表篇(上):顺序表

    数据结构探险之线性表篇 将要学到得: 线性表(链表) 什么是线性表? 线性表是n个数据元素的有限序列 排列之后成线...

  • 【数据结构】线性表之静态链表

    网易云课堂小甲鱼课程链接:数据结构与算法 一、什么是静态链表 C语言的伟大,在于指针的灵活性,使得它可以非常容易的...

  • 数据结构与算法之数组与链表

    线性表包括数组,链表(单链表,双向链表,循环链表,双向循环链表,静态链表),栈(顺序栈,链式栈),队列(普通队列,...

  • 数据结构与算法之栈与队列

    线性表包括数组,链表(单链表,双向链表,循环链表,双向循环链表,静态链表),栈(顺序栈,链式栈),队列(普通队列,...

  • 数据结构之线性表(下)

    单链表:通过指针连接的线性表 没有指针的语言如果表示链表?答案是静态链表,静态链表用数组表示,使用元素的物理位序来...

  • 数据结构探险之线性表下篇:链表通讯录

    数据结构探险之线性表下篇:链表 链表实现 顺序表的优缺点: 优点:遍历寻址很方便,基于数组效率高 缺点:插入时元素...

  • 13-数据结构探险系列-线性表篇

    数据结构探险之线性表篇 将要学到得, 线性表(链表) 整体的路线图如上图所示,线性表要比队列和栈编码上难一点,起到...

  • Java造轮子-数据结构-线性表

    数据结构-线性表 @(数据结构) 线性表是数据结构中的逻辑结构。可以存储在数组上,也可以存储在链表上。 顺序表(数...

  • iOS 数据结构之链表

    iOS 数据结构之链表 iOS 数据结构之链表

网友评论

    本文标题:【数据结构】线性表之静态链表

    本文链接:https://www.haomeiwen.com/subject/ybuckxtx.html