美文网首页
四、线性表(三)、线性表的顺序存储结构

四、线性表(三)、线性表的顺序存储结构

作者: 默默_David | 来源:发表于2020-05-20 21:59 被阅读0次

    数据结构目录

    顺序存储结构:

    用一段地址连续的存储单元依次存储线性表的数据元素,如数组。物理上的存储方式事实上就是在内存中找个初始地址,然后通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次放在这块空地中。

    线性表的顺序存储结构

    1. 线性表顺序存储的结构代码:

    #define MAXSIZE    100   //线性表最大容量
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    typedef int Status;
    
    typedef int ElemType;
    
    typedef struct{
        ElemType data[MAXSIZE];
        int length;//线性表的当前长度
    }SqList;
    
    

    顺序存储结构封装需要三个属性:

    • 存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置

    • 线性表的最大存储容量: 数组的长度MAXSIZE

    • 线性表的当前长度: length

    注意:数组长度是线性表存储空间的总长度,一般初始化后不变(部分语言可变是动态扩容,会影响性能,如Swift中空间不够则当前容量乘以2),而线性表的当前长度是线性表中元素的个数,是可变的

    数据元素ai的存储位置可以由a1推导出为:LOC(ai) = LOC(a1)+(i-1)*c(c为ElemType占用的存储单元(字节),LOC为location,位置)

    由这个公式,可以得出它的时间复杂度为O(1),通常将O(1)这种称为随机存储结构

    2.获得元素操作

    实现思想:将线性表L中的第i个位置元素值返回,如果过大或过小,或者线性表长度为0,则抛出异常

    GetElem操作

    /*
     Status是函数的类型,其值是函数结果状态代码,如OK等。
     初始条件:顺序线性表L已存在,1 <= i <= ListLength(L)
     操作结果:用e返回L中第i个元素的值
     */
    Status GetElem(SqList L,int i,ElemType *e)//注意这里的i是从1开始为有效,以后都一样
    {
        if (L.length == 0 || i < 1 || i > L.length) {
            return ERROR;
        }
        *e = L.data[i-1];
        return OK;
    }
    

    可以看到,线性表的顺序存储结构GetElem操作的时间复杂度为O(1)

    3. 插入操作

    实现思想:

    • 如果插入位置不合理,抛出异常

    • 如果线性表长度大于等于数组长度,则抛出异常或动态增加数组容量

    • 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置

    • 将要插入元素填入位置i处

    • 线性表长度+1

      ListInsert操作

    
    Status insertElem(SqList L,int i,ElemType e){
    
        /*
    
        线性表长度已经达到最大限制,抛出异常
    
        插入位置过小或过大,抛出异常
    
        */
    
        if (L.length == MAXSIZE || i < 1 || i > L.length+1) {
    
            return ERROR;
    
        }
    
        //从要插入的位置开始到结束,所有元素往后移动一位
    
        for (int j = L.length; j > i; j--) {
    
            L.data[j] = L.data[j-1];
    
        }
    
        //在i位置插入元素
    
        L.data[i-1] = e;
    
        //线性表长度加1
    
        L.length++;
    
        return OK;
    
    }
    
    

    按照最坏情况考虑时间复杂度,插入的时间复杂度为O(n)

    4. 删除操作

    实现思路:

    • 如果删除位置不合理,抛出异常

    • 取出删除元素

    • 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置

    • 线性表长度减一

      ListDelete操作

    
    Status deleteElem(SqList L,int i,ElemType *e){
        if (L.length == 0 || i < 1 || i > L.length) {
            return ERROR;
        }
        //取出第i个位置的数据返回
        *e = L.data[i-1];
        //从删除位置后一位开始,每个元素往前移动一位
        for (int j = i; j < L.length; j++) {
            L.data[j-1] = L.data[j];
        }
        //线性表长度减一
        L.length--;
    
        return OK;
    }
    
    

    按照最坏情况考虑时间复杂度,删除操作的时间复杂度为O(n)

    5.线性表顺序存储结构的优缺点:

    . 在存、读数据时,不管是哪个位置,时间复杂度都是O(1)。而在插入或删除时,时间复杂度都是O(n)

    . 这就说明,它比较适合元素个数比较稳定,不经常插入和删除元素,而更多的操作是存取数据的应用

    优点:

    . 无需为表示表中元素之间的逻辑关系而增加额外的存储空间

    . 可以快速地存取表中任意位置的元素

    缺点:

    . 插入和删除操作需要移动大量元素

    . 当线性表长度变化较大时,难以确定存储空间的容量

    . 容易造成存储空间的”碎片”

    相关文章

      网友评论

          本文标题:四、线性表(三)、线性表的顺序存储结构

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