• 计算机基础数据结构讲解第五篇-顺序表


      本篇及下一篇文章介绍线性表,包括线性表的定义及顺序表和链表的表示和方法。有关b树的补充等到之后进行介绍。

    一:线性表的定义和基本操作

      线性表是具有相同数据类型数据元素的有限序列集合,当线性表内没有元素时,是一个空表用a(i)代表第i个数据元素,第一个元素为表头,最后一个元素为表尾。除第一个元素外,每个元素都有一个直接前驱;除最后一个元素外,每个元素都有一个直接后继。
      线性表是一个逻辑结构,表示元素之间一一对应的关系;而顺序表和链式表是指存储结构。
      线性表的基本操作是最基本的操作,包括:
      InitList(&L):初始化一个空的线性表。
      Length(L):求表长。
      LocateElem(L,e):在表中查找给定关键字值的元素。
      GetElem(L,i):在表中查找第i个位置的元素的值。
      ListInsert(&L,i,e):在表中的第i个位置插入元素e。
      ListDelete(&L,i,&e):删除表中第i个位置元素,并用e返回。
      PrintList(L):输出线性表中的所有元素值。
      Empty(L):判断线性表是否为空。
      DestoryList(&L):销毁线性表,并释放线性表所占用的内存空间。
      这里的"&"表示的是c++里面的引用调用,传入指针变量的时候要对传入的指针进行改变,则会用到指针变量的引用型。在C语言的采用指针的指针也可以达到同样的效果。

    二:线性表的顺序存储

    1.定义

      线性表的顺序存储又称顺序表,用一组地址连续的存储单元依次存储线性表的数据元素,使逻辑上相邻的元素物理位置上也相邻。i为元素a(i)的位序,特点是表中的逻辑顺序与其物理顺序相同。
      有关顺序表的基本模型和结构这里就不详细介绍了,主要是顺序表是依靠数组实现的,要注意的是:线性表中元素的位序是从1开始的,而数组中元素的位序是从0开始的。

    2.顺序存储数据类型

      由于顺序表是由数组实现的,我们知道一维数组可以是静态分配的,也可以是动态分配的。静态分配因为空间和大小有限,一旦占满,再加入新的数据将会产生溢出,导致程序崩溃;动态分配,数组空间是在需要时通过动态存储语句分配,可以不断开辟新的存储空间,扩充存储空间,所以更高效。
      顺序存储数据类型实现的代码如下:

    // 顺序表的静态存储
    #define MaxSize 50          //顺序表最大长度
    typedef struct{
      ElemType data[MaxSize];  //顺序表数据元素
      int length;              //顺序表当前长度
    }SqList;                   //顺序表结构体类型定义
    
    //顺序表的动态存储
    #define InitSize 100       //表长度的初始定义
    typedef struct{
      ElemType *data;          //动态分配数组指针
      int MaxSize;length;      //数组最大容量和当前个数
    }SeqList;                  //顺序表结构体类型定义
    

      C语言初始动态分配语句是:
    L.data= (ElemType)malloc(sizeof(ElemType)InitSize);
      C++的动态分配语句是:
    L.data = new ElemType(InitList);

    3.顺序表基本操作的实现(代码写的是静态存储,动态存储类似)

    (1)插入操作

      在顺序表L的第i个位置插入新元素e。如果i的输入不合法,则返回false,表示插入失败;否则将原顺序表的第i个元素及其后面的所有元素右移一个位置,腾出一个空间插入新元素e。顺序表的长度加一,插入成功,返回true。插入位置范围从1到L.length+1,代码如下:

    bool ListInsert(SqList &L,int i,ElemType e){
      if(i < 1|| i > Length + 1)
        return false;
      if(L.length >= MaxSize)     //当前存储空间已满,不能插入
        return false;
      for(int j = L.length;j >= i;j--){     //将i及之后的元素后移
        L.data[j] = L.data[j-1];
      }
      L.data[i-1] = e;  //数组从0开始
      L.length++;
      return true;
    }
    

      插入操作的最好情况是在表尾插,后移操作不再进行;最坏情况是在表头插,后移n次。而平均情况下,插入的平均时间复杂度是O(n)。

    (2)删除操作

      删除表中的第i个位置的元素,成功返回true,并将被删除的元素用引用变量e返回,否则返回false,也需要移动元素位置。删除位置范围从1到L.length,代码如下:

    bool ListDelete(SqList &L,int i,ElemType &e){
      if(i < 1|| i > Length)
        return false;
      e = L.data[i-1];
      for(int j = i;j < L.length;j++){     //将i及之后的元素前移
        L.data[j-1] = L.data[j];
      }
      L.length--;
      return true;
    }
    

      插入操作的最好情况是在表尾插,前移操作不再进行;最坏情况是在表头插,前移n-1个数据元素。而平均情况下,删除的平均时间复杂度是O(n)。

    (3)简单的按值查找

      在顺序表中查找第一个元素值等于e的元素,并返回其位序。代码如下:

    int LocateElem(SqList L,ElemType e){
      int i;
      for(i = 0;i < L.length;i++)
        if(L.data[i] == e)
          return i + 1;             //位序从一开始
      return 0;
    }
    

      最好情况在表头比较一次,在表尾或不存在比较n次,按值查找的平均时间复杂度为O(n)。

    4.顺序表的特点

      优点:随机访问,在O(1)的时间内找到指定的元素。存储密度高,每个结点只存储数据元素。
      缺点:插入和删除操作需要移动大量元素。

  • 相关阅读:
    1、jQuery基本认识
    Zabbix agent 启动报错:cannot set resource limit [13] Permission denied
    Zabbix agent启动报错:cannot create semaphore set
    Windows系统版本号对照表
    学习使用 vue mixin
    windows cmd 生成文件目录树
    合村并镇
    Adobe宣布今年12月31日正式终止支持Flash
    好春光
    npm package version
  • 原文地址:https://www.cnblogs.com/ITXiaoAng/p/13580219.html
Copyright © 2020-2023  润新知