【数据结构与算法】第二章:线性表及其顺序表示

简介: 线性表、栈、队列、串和数组都属于线性结构。线性结构的基本特点是除第一个元素无直接前驱,最后一个元素无直接后继之外,每个元素都有一个前驱和后继。线性表示最基本切最常用的一种线性结构,同时也是其他数据结构的基础,尤其单链表,是贯穿整个数据结构的基本技术。

🙊🙊作者主页:🔗求不脱发的博客

📔📔 精选专栏:🔗数据结构与算法

📋📋 精彩摘要:线性表、栈、队列、串和数组都属于线性结构。线性结构的基本特点是除第一个元素无直接前驱,最后一个元素无直接后继之外,每个元素都有一个前驱和后继。线性表示最基本切最常用的一种线性结构,同时也是其他数据结构的基础,尤其单链表,是贯穿整个数据结构的基本技术。

💞💞觉得文章还不错的话欢迎大家点赞👍➕收藏⭐️➕评论💬支持博主🤞


📚目录

📖【数据结构与算法】第二章:线性表

📝1️⃣初始线性表

📝2️⃣线性表的顺序表示和实现

📝3️⃣顺序线性表的插入(插在第i个结点之前)

📝4️⃣顺序线性表的删除(删除第i个结点)


📖【数据结构与算法】第二章:线性表


📝1️⃣初始线性表

线性结构

定义:若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,并且所有结点都最多只有一个直接前驱和一个直接后继。

可表示为:(a1 , a2, a3, ...,an)。

特点:

    • 只有一个首结点和尾结点
    • 除首尾结点外,其他结点只有一个直接前驱和一个直接后继。

           简言之,线性结构反映结点间的逻辑关系是一对一的,线性结构包括线性表、堆栈、队列、字符串、数组等等。其中,最典型、最常用的是线性表。

    线性表

           在日常生活中,线性表的例子比比皆是。例如26个英文字母的字母表,(A, B, C, ..., Z) 就是一个线性表,表中的数据元素是单个字母。在稍微复杂的线性表中,一个数据元素可以包含若干个数据项。

           形如字母表,他们的数据元素虽然不同,但同一线性表中的元素,必定具有相同的特性,即属于同一数据对象,相邻数据元素之间存在着序偶关系。

    定义:由n(n>=0)个数据特性相同的元素构成的优先序列。

    image.gif编辑

    特点:

      • 存在唯一的一个被称作“第一个”的数据元素
      • 存在唯一的一个被称作“最后一个”的数据元素
      • 除第一个之外,结构中的每个数据元素均只有一个前驱
      • 除最后一个之外,结构中的每个数据元素均只有一个后继

      重要基本操作:

      image.gif编辑


      📝2️⃣线性表的顺序表示和实现

      线性表的顺序表示又称为顺序存储结构或顺序映像。

      顺序存储

      image.gif编辑

      定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构。简言之,逻辑上相邻,物理上也相邻。

      存储方法:用一组地址连续的存储单元一次存储线性表的元素,可通过数组V [n] 来实现。

      特点:

        1. 利用数据元素的存储位置标示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构一致。
        2. 在访问线性表时,可以快速的计算出任何一个数据元素的存储地址,因此可以粗略地认为,访问每个元素所花时间相等。‘
        3. 存储密度大(结点本身所占存储量 / 结点结构所占存储量)
        4. 可以随机存取表中任一元素

        这种存取元素的方法被称为随机存取法

        缺点:

          1. 在插入、删除某一元素时,需要移动大量元素。
          2. 浪费存储空间
          3. 属于静态存储形式,数据元素的个数不能自由扩充。

          类型定义:

          #define MAXSIZE 100    //最大长度
          typedef struct
          {
              ELemType *elem;    //指向数据元素的基本地址
              int length;    //线性表的当前长度
          }SqList;

          image.gif

          例如:图书表的顺序存储结构类型定义:

          #define MAXSIZE 10000    //图书表可能达到的最大长度
          typedef struct    //图书信息定义
          {
              char no[20];    //图书ISBN
              char name[50];    //图书名字
              float price;    //图书价格
          }Book;
          typedef struct    //图书信息定义
          {
              Book *elem;    //存储空间的基地址
              int length  //图书表中当前图书个数
          }SqList;    //图书表的顺序存储结构类型为 SqList

          image.gif

          ✨初始化线性表(引用参数类型)

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

          image.gif

          ✨初始化线性表(参数用指针)

          Status InitList_Sq(SqList *L)    //构造一个空的顺序表L
          {
              L-> elem = new ElemType[MAXSIZE];    //为顺序表分配空间
              if(!L->elem) exit(OVERFLOW);    //存储分配失败
              L->length = 0;    //空表长度为 0 
              return OK;
          }

          image.gif

          ✨几个简单基本操作的算法实现

          销毁线性表

          void DestroyList(SqList &L)
          {
              if(L.elem) delete[]L.elem;   //释放存储空间
          }

          image.gif

          清空线性表

          void ClearList(SqList &L)
          {
              L.length=0;    //将线性表的长度置为0
          }

          image.gif

          求线性表的长度

          int GetLength(SqlList L)
          {
              return (L.length);
          }

          image.gif

          判断线性表是否为空

          int IsEmpty(SqList L)
          {
              if(L.length == 0)
                  return 1;
              else return 0;
          }

          image.gif

          获取线性表中某个元素的内容

          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;
          }

          image.gif

          顺序查找(根据指定数据获取数据所在的位置)

          int LocateElem(SqList, ElemType e)
          {
              for(int i = 0; i < L.length; i++)
                  if(L.elem[i] == e) return i+1;
              return 0;
          }

          image.gif

          📝3️⃣顺序线性表的插入(插在第i个结点之前)

          ✨算法步骤

            1. 判断插入位置i是否合法
            2. 判断顺序表的存储空间是否已满
            3. 将第n到第i位的元素依次向后移动一个位置,空出第i个位置。
            4. 将要插入的新元素e放入第i个位置
            5. 表长+1,插入成功返回OK

            ✨算法描述

            在线性表中第i个数据元素之前插入数据元素e

            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] = e;    //将新元素e放入第i个位置
                ++L.length;    //表长+1
                return OK;
            }

            image.gif

            ✨算法分析

            算法时间只要耗费在移动元素的操作上。

            如果插入在尾结点之后,则无需移动(速度较快)

            如果元素全部后移(速度较慢)

            如果考虑在各种位置插入(n + 1种可能)的平均移动次数则

            image.gif编辑

            最终可得AMN = n/2


            📝4️⃣顺序线性表的删除(删除第i个结点)

            ✨算法步骤

              1. 判断删除位置i是否合法(合法值为 1 <= i <= n)
              2. 将于删除的元素保留在e中
              3. 将第 i+1 至 第 n 位的元素依次向前移动有一个位置
              4. 表长-1,删除成功返回OK

              ✨算法描述

              将线性表中第i个数据元素删除

              Status ListDelete_Sq(SqList & L,int i)
              {
                  if(i < 1 || i > L.length) return ERROR;    //i值不合法
                  for( j = i; j < L.length ; j ++)
                      L.elem[j - 1] = L.elem[j];    //将被删除元素之后的元素前移一位
                  --L.length;    //表长-1
                  return OK;
              }

              image.gif

              ✨算法分析

              算法时间主要耗费在移动元素的操作上

              若删除尾结点,则无需移动(速度较快)

              若删除首结点,则表中n-1个元素全部前移(速度较慢)

              若考虑在各种位置(n中可能)删除的平均移动次数

              image.gif编辑

              最终计算得 AMN = (n-1)/  2。

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

              相关文章
              |
              5月前
              |
              存储 C语言
              数据结构中的线性表链式存储介绍及其基本操作
              链式存储是线性表的一种重要存储方式,它通过节点和指针的结构,实现了灵活的动态存储管理。本文介绍了单向链表的基本操作,并提供了相应的C语言代码示例。理解和掌握链表的操作对学习和应用数据结构具有重要意义。希望这篇博客能帮助你更好地理解线性表的链式存储。
              128 2
              |
              1月前
              |
              存储 Java
              数据结构第二篇【关于java线性表(顺序表)的基本操作】
              数据结构第二篇【关于java线性表(顺序表)的基本操作】
              30 6
              |
              18天前
              |
              算法 安全 搜索推荐
              2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
              IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
              |
              1月前
              |
              存储
              【数据结构】线性表和顺序表
              【数据结构】线性表和顺序表
              22 1
              |
              5月前
              |
              算法
              数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
              数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
              48 0
              |
              1月前
              01(数据结构考研)线性表相关操作代码
              01(数据结构考研)线性表相关操作代码
              59 0
              |
              1月前
              |
              存储 C语言
              数据结构之线性表的初始化及其操作
              数据结构之线性表的初始化及其操作
              36 0
              |
              2月前
              |
              存储 Java
              java数据结构,线性表顺序存储(数组)的实现
              文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
              |
              5月前
              |
              存储 测试技术
              【数据结构】操作受限的线性表,栈的具体实现
              【数据结构】操作受限的线性表,栈的具体实现
              60 5
              |
              5月前
              |
              存储 测试技术
              【数据结构】操作受限的线性表,队列的具体实现
              【数据结构】操作受限的线性表,队列的具体实现
              45 4