【数据结构】线性表

文章目录

  • 2.1 线性表的定义和特点
    • 2.1.1 线性表的定义
    • 2.1.2 线性表的逻辑特征
  • 2.2 线性表的应用案例
    • 2.2.1 一元多项式的运算:
    • 2.2.2 稀疏多项式的计算
    • 2.2.3 图书信息管理系统
  • 2.3 线性表的类型定义
    • 2.3.1 基本操作

【数据结构】线性表_第1张图片

2.1 线性表的定义和特点

由n个相同类型数据元素组成的表称作线性表

【数据结构】线性表_第2张图片
类似于数组,a1是数组的第一个元素an为最后一个元素。

2.1.1 线性表的定义

n(n >= 0) 个数据元素(结点)a1,a2,…an组成的有限序列

  • 其中数据元素的个数 n 定义为表的长度。
  • n = 0 (表中没有元素) 时称为空表
  • 将非空的线性表(n > 0)记作:(a1,a2…an)。
  • 这里的数据元素ai(1 <= i <= n)只是一个抽象的符号,其具体含义在不同的情况下可以不同。

线性表的例子

【例1】分析26个英文字母组成的英文表(A,B,C,D…Z)

  • 数据元素都是字母。
  • 元素之间的关系是线性:除了A(表头)和 Z(表尾)其他的字母前后都各有一个字母。
  • 字母的前后关系不能翻转。

【例2】分析学生情况登记表

【数据结构】线性表_第3张图片
每一行的学生信息就是数据元素

总结

  • 同一线性表中的元素必定具有相同特性,(字母表中就都是字母,学生表中就都是学生信息)
  • 数据元素之间的关系是线性关系

2.1.2 线性表的逻辑特征

在非空的线性表

  • 有且仅有一个开始结点a1,它没有直接前趋,而仅有一个直接后继a2.
  • 有且仅有一个终端结点an,他没有直接后继,而仅有一个直接前趋an-1
  • 其余的内部结点ai(2 <= i <= n-1),都有且仅有一个直接前趋 ai-1,和一个直接后继 ai+1

线性表是一种典型的线性结构

2.2 线性表的应用案例

2.2.1 一元多项式的运算:

  • 实现两个多项式 加、减、乘运算。

在这里插入图片描述
把这个多项式每一项的系数拿出来,做成一个线性表。
每一项的指数,就用系数的下标来表示,(下标为0指数就是0,下标为1指数就是1…)。
线性表 P = (P0, P1, P2… pn),系数就可以用数组来存储了。

【数据结构】线性表_第4张图片

  • 如果给的是个稀疏多项式呢?

    • S(x) = 1 + 3x ^ 10000 + 2x ^ 20000
    • 如果这样的多项式还像上面那样来表示,指数(下标i)就要一直跑到20000去了,这样会造成很大的浪费。
    • 所以只需要记录下每一项的系数是对应多少指数的就可以了,只需要记录系数不为0的项
      【数据结构】线性表_第5张图片

2.2.2 稀疏多项式的计算

只将系数不为0的每一项的系数和指数存储起来
线性表P = ((p1,e1),(p2,e2),...(pm,em))

【数据结构】线性表_第6张图片
A和B的线性表的内容看起来就像是用二维数组存储了起来。

求这两个多项式的和:

线性表A = ((7,0),(3,1),(9,8),(5,17))
线性表B = ((8,1),(22,7),(-9,8))

  • 创建一个新数组C
  • 分别从头遍历比较a和b的每一项。
    • 指数相同,对应系数相加,若其和不为0,则在c中增加一个新项。
    • 指数不相同,则将指数交小的项复制到c中。
  • 一个多项式已经遍历完毕时,将另一个圣域项依次复制到C中即可
    【数据结构】线性表_第7张图片
  1. 先把AB两个数组的第一个元素的指数比较,A里面存的指数是0,比较小,先把A的第一个元素(7,0)存到C数组中,A的第一项去掉不再参与计算。
    【数据结构】线性表_第8张图片

  2. 将A的第二项(3,1)和B的第一项(8,1)的指数比较,指数相同(1),则系数相加存入C,指数不变存入C,这两项去掉。
    【数据结构】线性表_第9张图片

  3. 再将A的(9,8)和B的(22,7)比较,B的指数比较小,将(22,7)存入C数组,然后去掉不再参与计算。
    【数据结构】线性表_第10张图片

  4. 将A的(9,8)和B的(-9,8)比较,指数相同,则系数相加,系数相加为0,则这两项都删掉且不存入C数组。
    【数据结构】线性表_第11张图片

  5. 最后将剩下的最后一项存入数组C中,至此计算完毕。
    【数据结构】线性表_第12张图片

数组C应该多大?

  • 最多,线性表A和B的每一项的指数都不同,那么数组C就要7项。
  • 最少,A和B每一项的指数都相同,且系数为相反数,那么结果就刚好是0项
  • 给C的空间如果多了有可能浪费,少了就有可能放不下,这个时候就需要用到链式存储结构了。

顺序存储结构存在的问题

  • 存储空间分配不灵活
  • 运算的空间复杂度高

链式存储结构

不用数组来存储A和B的数据元素,不占用一块连续的空间,用链表的方式来存储,运算的时候需要多少就用多少空间。

【数据结构】线性表_第13张图片

2.2.3 图书信息管理系统

需要的功能:查找 、插入 、 删除 、修改 、排序 、计数

【数据结构】线性表_第14张图片

  • 图书表可以抽象为线性表(顺序表或链表)。
  • 表中每本图书抽象为线性表中的数据元素。

总结

  • 线性表中数据元素的类型可以为简单类型,也可以为复杂类型
  • 许多实际应用问题所涉及的基本操作有很大相似性,不应该为每个具体应用单独编写一个程序。
  • 从具体应用中抽象出共性的逻辑结构和基本操作(抽象数据类型)。然后实现其存储结构和基本操作

2.3 线性表的类型定义

抽象数据类型线性表的定义:

【数据结构】线性表_第15张图片

2.3.1 基本操作

  • 初始化线性表 (lnitlist(&L))

    • 操作结果:构造一个空的线性表L
  • 销毁线性表(DestoryList(&L))

    • 初始条件:线性表 L 已经存在。
    • 操作结果:销毁线性表 L,内存中再没有这个线性表。
  • 清除线性表(ClearList(&L))

    • 初始条件:线性表 L 已经存在。
    • 操作结果:将线性表 L 里面的内容重置。
  • 判断线性表是否为空(ListEmpty(L))

    • 初始条件:线性表 L 已经存在。
    • 操作结果:如果线性表为空表(表里面没有元素),则返回TURE,反之返回FALSE。
  • 求线性表长度 (ListLength(L))

    • 初始条件:线性表 L 已经存在。
    • 操作结果:返回线性表 L 中的数据元素的个数。
  • 获取线性表元素(GetElem(L,i,&e))

    • 初始条件:线性表 L 已经存在,取第 i 个元素,i 的取值范围,1 <= i <= 线性表长度(第一个元素合和最后一个元素之间)
    • 操作结果:用 e 接收线性表 L 中第 i 个数据元素的值。
  • 查找和定位元素(LocateElem(L,e,compare()))

    • 初始条件:线性表 L 已经存在,compare()是数据元素判定函数,找大于小于或等于 e 的元素。
    • 操作结果:返回 L 中第一个与 e 满足copmare()的数据元素的位序,若这样的数据元素不存在则返回值0.
    • 个人理解敲了段用二分法查找某个数字的代码
int compare(int* L,int e,int sz)
{
        int left = 0;
        int right = sz -1;

        while(left <= right)
        {
                int mid = (left + right) / 2;
                if(e < L[mid])
                {
                        right = mid -1;
                }
                else if(e > L[mid])
                {
                        left = mid + 1;
                }
                else
                {
                        return mid;
                }
        }
        return 0;
}
int main()
{
        int e = 6;
        int L[]= {1,2,3,4,5,6,7,8,9,10};
        int sz = sizeof(L)/sizeof(L[0]);

        if(compare(L,e,sz))
        {
                printf("找到了,下标是%d\n",compare(L,e,sz));
        }
        else
        {
                printf("找不到了\n");
        }
        return 0;
}
  • 获得元素的前趋(PriorElem(L,cur_e,&pre_e))
    • 初始条件:线性表 L 已经存在
    • 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e接收它的前趋(前一个元素),反之操作失败,pre_e无意义。
  • 获得元素的后继(NextElem(L,cur_e,&next_e))
    • 初始条件:线性表 L 已经存在
    • 操作结果:若cer_e是 L 的数据元素,且不是最后一个,则用 next_e 接收它的后继,反之操作失败,next_e无意义。
  • 在线性表中插入一个元素(Lisrinsert(&L,i,e))
    • 初始条件:线性表 L 已经存在,插入位置范围 1 <= i < =Listlength(L)+1,可以在第一个位置插入,也可以插入在最后一个元素之后。
    • 操作结果:在 L 的第 i 个位置之前插入新的数据元素 e ,L的长度加一。
      【数据结构】线性表_第16张图片
  • 删除第 i 个元素(ListDlete(&L,i,&e))
    • 初始条件:线性表 L 已经存在,删除元素 i 的位置, 1<= i <= ListLength(L),从第一个到最后一个元素。
    • 操作结果:删除 L 的第 i 个数据元素,并用 e 接收被删除的值,L 的长度减一。
      【数据结构】线性表_第17张图片
  • 编历每个元素(ListTraverse(&L,visited()))
    • 初始条件:线性表 L 已经存在
    • 操作结果:依次对线性表中每个元素调用visited()访问一线。

你可能感兴趣的:(数据结构,算法,python)