线性表的顺序存储结构

这篇具有很好参考价值的文章主要介绍了线性表的顺序存储结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、线性表的定义

     线性表:是具有相同数据类型的n(n>=0)个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。    记作   ( a1, ..., ai, ai+1, ..., an )   其中ai是线性表中的数据元素, n是表的长度

   存在唯一的一个被称做“第一个”的数据元素 (如a1 )
   存在唯一的一个被称做“最后一个”的数据元素 (如an )
   除第一个数据元素外,其他元素均只有一个直接前驱
   除最后一个数据元素外,其他元素均只有一个直接后继

   特点:

      1.表中元素的个数有限

      2.表中元素具有逻辑上的顺序性,表中元素有其先后次序

      3.表中元素都是数据元素,每个元素都是单个元素

      4.表中元素的数据类型都相同,即每个元素都占有相同大小的存储空间。

      5.表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容。

  注:线性表是一种逻辑结构,表示元素之间一对一的相邻关系,顺序表和链表是指存储结构。

  基本数据类型是一些不可再划分的数据,一般就是整形、浮点型、以及字符型。
  抽象数据类型(ADT):指从问题中抽象出来的一个数据模型以及定义在此数据模型上的一组操作,不考虑计算机的具体存储结构与运算的具体实现算法。

   ADT 抽象数据类型名{
      D: 数据对象:<数据对象的定义>
      S: 数据关系:<数据关系的定义>
      P: 基本操作:<基本操作的定义>
} ADT 抽象数据类型名

描述线性表

ADT List {
     数据对象:D = { ai | ai属于元素集,(i = 1,2,...,n,n>=0)}
     数据关系:R = { <ai-1,ai> | ai-1,ai属于D,(i = 2,3,...,n)}
     基本操作:
          InitList(&L): 初始化表。构造一个空的线性表。

          Length(L):求表长。返回线性表L的长度。

          LocateElem(L,e):按值查找操作。在表L中查找具有给定关键字值的元素。

          GetElem(L,i):按位查找操作。获取表L中第i个位置的元素的值。

           ListInsert(&L,i,e):插入操作。在表L中的第i个位置插入指定元素e。

           ListDelete(&L,i,&e):删除操作。删除表L中第i个位置上的元素,并用e返回删除元素的值。

           PrintList(L):输出操作。按前后顺序输出线性表L的所有元素值。

           Empty(L):判空操作。若L为空表,则返回true,否则返回false。

           DestroyList(&L):销毁操作。销毁线性表,并释放线性表L所占用的内存空间。
}ADT List

二、顺序表的定义

   顺序表:线性表的顺序存储叫做顺序表。

   顺序存储结构:指的是用一段地址连续的存储单元依次存储线性表的数据元素。

       可以用一维数组来实现顺序存储结构,即把第一个数据元素存到数组下标为0的位置中,接着把顺序表相邻的元素存储在数组中相邻的位置。

       顺序表特点:表中元素的逻辑顺序与其物理顺序相同。

       线性表的顺序存储结构是一种随机存取的存储结构。

       线性表中元素的位序是从1开始的,而数组中元素的下标是从0开始的。

如何分配空间?
静态分配
      1、 在程序编译或运行过程中,按事先规定大小分配内存  空间的分配方式。int a [10]
      2、 必须事先知道所需空间的大小。
      3、 分配在栈区或全局变量区,一般以数组的形式。
      4、 按计划分配。
      在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定 。

动态分配

      1、在程序运行过程中,根据需要大小自由分配所需空间。
      2、按需分配。
      3、分配在堆区,一般使用特定的函数进行分配。

注:

   malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
   sizeof(x)运算,计算变量x的长度
   free(p)函数,释放指针p所指变量的存储空间

假定线性表的元素类型为ElemType,则线性表的顺序存储类型描述为:

   #define    MaxSize  50                              //定义线性表的最大长度

   typedef    struct{

         ElemType    data [MaxSize];              //顺序表的元素

         int     length;                                      //顺序表的当前长度

    }SqList;                                                 //顺序表的类型定义

   void InitList(SeqList& L) {
       L.elem=new ElemType[MAXSIZE];
        //L.data[0] = 0;
        // L.data[1] = 0;
        L.Length = 0 ;
printf("顺序表初始化成功!\n");
}

注:typedef int ElemType;//定义ElemType为int类型,想让它是什么类型,用typedef重定义就行。

一维数组可以是静态分配,也可以是动态分配。

  静态分配时:由于数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据就会产生溢出,进而导致程序崩溃。

  动态分配时:存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,就另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储数组空间的目的。  

  #define InitSize 10 //定义顺序表的初始长度

  typedef    struct{

     ElemType  *data;      //指示动态分配数组的指针,也就是malloc函数返回的分配空间的起始地址
     int MaxSize; //顺序表的最大容量
     int length; //顺序表当前长度
  }SeqList;


 void InitList(SqList& L) {
      L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize);   //C的初始动态分配语句

      //L.data=new ElemType[InitSize];            //C++的初始动态分配语句
      L.MaxSize = InitSize;
      L.length = 0;
      printf("顺序表初始化成功!\n");
}

动态分配存储空间时,如果原先分配的存储空间不足时可以继续申请空间。按照之前设置的增量来增加存储容量。
    int* newbase = (int*)realloc(L.data, sizeof(int) * (InitSize + ListIncrement));
    指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小),在原有的空间上增加空间

    功能:先判断当前的指针是否有足够的连续空间,如果有,扩大指向的地址,并且将地址返回,如果空间不够,先按照新的大小指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

注:动态分配物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时动态决定。

三、顺序表的基本操作

   初始化顺序表L (参数用引用)
      Status InitList_Sq(SqList &L){             //构造一个空的顺序表L
      L.elem=new ElemType[MAXSIZE];    //为顺序表分配空间
      if(!L.elem) return error;                       //存储分配失败
      L.length=0;                                        //空表长度为0
      return OK;
     }

  初始化顺序表L (参数用指针)
    Status InitList_Sq(SqList *L){                 //构造一个空的顺序表L
    L-> elem=new ElemType[MAXSIZE];    //为顺序表分配空间
    if(!L.elem) return error;                          //存储分配失败
    L-> length=0;                                        //空表长度为0
    return OK;
  }

销毁线性表L
   void DestroyList(SqList &L){
         if (L.elem) delete L.elem;             //释放存储空间 等同于free(L.elem);
   }
清空线性表L
   void ClearList(SqList &L){
        L.length=0;                                   //将线性表的长度置为0
}

求顺序表L的长度
   int GetLength(SqList L){
      return L.length;
 }

判断顺序表L是否为空
   int IsEmpty(SqList L){
         if (L.length==0)
             return 1;
         else
            return 0;
}

获取元素值(根据位置i获取相应位置数据元素的内容
int GetElem(SqList L,int i,ElemType &e){
         if (i<1||i>L.length)
            return ERROR;                     //判断i值是否合理,若不合理,返回ERROR
        e=L.elem[i-1];                           //第i-1的单元存储着第i个数据
        return OK;
}

在顺序表L中查找第一个元素值等于e的元素,并返回其位序

int LocateElem(Sqlist L,ElemType e){

         int i;

         for((i=0;i<L.length;i++){

             if(L.data[i]==e)

                return i+1;                     //下标为i的元素值为e,返回其位序i+1

          } 

         return 0;

}

     最好情况:查找的元素就在表头,仅需比较一次,时间复杂度为O(1)

     最坏情况:查找的元素在表尾(或不存在)时,需要比较n次,时间复杂度为O(n)

     平均情况:需要比较的次数为(n+1)/2  时间复杂度为O(n)

插入元素(在顺序表L中第i个数据元素之前插入数据元素e )
(1)判断插入位置i 是否合法。
(2)判断顺序表的存储空间是否已满。
(3)将第n至第i 位的元素依次向后移动一个位置,空出第i个位置。
(4)将要插入的新元素e放入第i个位置。
(5)表长加1,插入成功返回OK。
       Status ListInsert_Sq(SqList &L,int i ,ElemType e){
           if(i<1 || i>L.length+1) return ERROR;                                 //i值不合法
           if(L.length==MAXSIZE) return ERROR;                            //当前存储空间已满
           for( j=L.length-1;j>=i-1;j--)
              L.elem[ j+1]=L.elem[ j];                                                  //插入位置及之后的元素后移
           L.elem[i-1]=e;                                                                  //将新元素e放入第i个位置
           ++L.length;                                                                     //表长增1
           return OK;
           }

    最好情况:在表尾插入(即i=n+1),元素后移语句将不执行,时间复杂度为O(1)

    最坏情况:在表头插入(即i=1),元素后移语句将执行n次,时间复杂度为O(n)

    平均情况:需要移动的次数为n/2   时间复杂度为O(n)

删除元素(将顺序表L中第i个数据元素删除)
(1)判断删除位置i 是否合法(合法值为1≤i≤n)。
(2)将第i+1至第n 位的元素依次向前移动一个位置。
(3)表长减1,删除成功返回OK。

 将被删元素赋给引用变量e

   Status  ListDelete(SqList  &L,int  i,Elemtype  &e){

        if(i<1||i>L.length)     return   false;

        e=L.data[i-1];                                                      //将被删除的元素赋值给e

        for(int  j=i;j<L.length;j++)                                   //将第i个位置后的元素前移

            L.data[j-1]=L.data[j];

         L.length--;                                                        //线性表长度减1

         return  true;

     }

    最好情况:删除表尾元素(即i=n),无须移动元素,时间复杂度为O(1)

    最坏情况:删除表头元素(即i=1),需移动除表头元素外的所有元素,时间复杂度为O(n)

    平均情况:需要移动的次数为(n-1)/2,时间复杂度为O(n)

查找、插入、删除算法的平均时间复杂度为O(n)
顺序表的空间复杂度S(n)=O(1)(没有占用辅助空间)

顺序表特点:

优点:
    存储密度大(结点本身所占存储量/结点结构所占存储量)
    可以随机存取表中任一元素
缺点:
     在插入、删除某一元素时,需要移动大量元素
     表长变化大时候,存储空间难以确定
 文章来源地址https://www.toymoban.com/news/detail-788987.html

到了这里,关于线性表的顺序存储结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】二、线性表的顺序表示【硬核】

    图书表的顺序存储结构类型定义: 在调用函数的过程中,当形参为引用类型时,实参和形参占用了相同的空间 2.4.1 线性表的基本操作: 2.4.2 线性表L的初始化 2.4.3 销毁和清空线性表L 2.4.4 求线性表L的长度以及判断线性表L是否为空 2.4.5 顺序表的取值(根据位置i获取相应位置

    2023年04月26日
    浏览(48)
  • 数据结构(王道)——线性表的存储结构之循环表

      创建并初始化、判断循环单链表是否为空、判断结点p是否为循环单链表的表尾结点的代码操作。           创建并初始化、判断循环双链表是否为空、判断结点p是否为循环双链表的表尾结点的代码操作。     普通双链表用以下代码实现插入的时候,如果插入的结点是最后

    2024年02月16日
    浏览(38)
  • C/C++数据结构---顺序表---线性存储结构

    个人主页: 仍有未知等待探索_小项目,洛谷刷题,数据结构-CSDN博客 专题分栏---数据结构: 数据结构_仍有未知等待探索的博客-CSDN博客 目录 一、知识储备 二、引例  三、顺序表 第一步,先创建一个顺序表类型 第二步,定义和初始化顺序表    第三步,顺序表的基本操作

    2024年02月08日
    浏览(41)
  • 数据结构 线性表的定义和基本操作(以顺序表为例)

    名人说:一花独放不是春,百花齐放花满园。——《增广贤文》 作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊) 以下代码个人分享出来,仅供学习交流,且仅在CSDN平台发布,未经授权禁止二次转发。 〇、线性表是什么? 1、定义 线性表 是具有 相同数据类型 的 n(

    2024年02月12日
    浏览(58)
  • 【数据结构】线性表(一)线性表的定义及其基本操作(顺序表插入、删除、查找、修改)

    目录 一、线性表 1. 线性表的定义 2. 线性表的要素 二、线性表的基本操作 三、线性表的顺序存储结构 1. 定义 2. 顺序表的操作       a. 插入操作 b. 删除操作 c. 查找操作 d. 修改操作 e. 代码实例          一个线性表是由零个或多个 具有相同类型的结点 组成的有序集合。

    2024年02月03日
    浏览(64)
  • 数据结构-线性表的链式存储(包含代码实现)

    链式存储结构 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻 线性表的链式存储结构又称为 非顺序映像 或 链式映像。 用一组 物理位置任意的存储单元 来存放线性表的数据元素 这组存储单元既可以是连续的,也可以是不连续的,甚至是零散

    2024年02月06日
    浏览(52)
  • 数据结构(王道)——线性表之静态链表&顺序表和链表的比较

      如何定义一个静态链表     初始化静态链表:   静态链表的查找、插入、删除           创: 销:   增、删:   查:   顺序表、链表该如何选择?  

    2024年02月16日
    浏览(104)
  • 数据结构-线性表的顺序表基本操作代码实现(超级详细清晰 C++实现)

    顺序表是用一段 物理地址连续的存储单元 依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 顺序表: 可动态增长的数组,要求数据是连续存储的 特点: 随机访问 顺序既可以 静态分配 ,也可以 动态分配 。在静态分配时,由于数组

    2024年02月07日
    浏览(54)
  • 线性表的顺序存储结构

    一、线性表的定义      线性表:是具有相同数据类型的n(n=0)个数据元素的有限序列,其中n为表长,当n=0时,线性表是一个空表。    记作   ( a1, ..., ai, ai+1, ..., an )   其中ai是线性表中的数据元素, n是表的长度    存在唯一的一个被称做“第一个”的数据元素 (如a1 )

    2024年02月01日
    浏览(34)
  • 【数据结构】线性表(顺序存储和链式存储)两种方法,细节满满,保你学会

    ⭐⭐⭐⭐⭐⭐ 🎊专栏【数据结构】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【勋章】 大一同学小吉,欢迎并且感谢大家指出我的问题🥰 ⭐⭐⭐⭐⭐⭐  目录 ⭐定义:  ⭐ 理解: ⭐存储方式 : ⭐顺序存储的优缺点: 优点: 缺点: ⭐链式存储的优

    2023年04月09日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包