线性表

顺序表

优点

  • 逻辑上相邻元素的物理位置一定相邻
  • 随机存取(时间复杂度为 \(O(1)\),最大优势)
  • 存储密度大

缺点

  • 插入,删除需要大量移动元素
  • 会产生存储碎片

建表属性

  • 起始位置,数组名n,最大存储容量maxsize,长度length

建表方式

静态建表

  • 数组是静态分配的,大小固定

动态建表

  • 存储空间可以动态分配,即在程序执行过程中,通过动态分配语句分配

!动态建表非链式存储

移动元素个数

  • 在含有 \(n\) 个元素的线性表中第 \(i\) 个位置插入一个元素需要移动的元素个数为 \(n-i+1\)
  • 在含有 \(n\) 个元素的线性表中第 \(i\) 个位置删除一个元素需要移动的元素个数为 \(n-i\)

移动元素平均次数

  • 在含有 \(n\) 个元素的线性表中第 \(i\) 个位置插入一个元素需要移动的元素的平均次数为 \(\frac{n}{2}\)
  • 在含有 \(n\) 个元素的线性表中第 \(i\) 个位置删除一个元素需要移动元素的平均次数 \(\frac{n-1}{2}\)
  • 对具有 \(n\) 个元素的顺序表顺序查找,查找成功的平均查找长度(ASL,平均查找次数)为 \(\frac{n+1}{2}\)

时间复杂度

  • 增删查的平均时间复杂度均为 \(O(n)\);若给定序号则时间复杂度为 \(O(1)\);若给定值时间复杂度仍为 \(O(n)\);顺序表有序,折半查找为 \(O(\log_2n)\)

链表

优点

  • 便于插入、删除操作,克服了顺序表插入、删除操作时需要移动大量元素的缺点
  • 链式结构不需要大量移动元素,只需要修改指针
  • 可以使用指针反映数据间的逻辑关系
  • 所需空间与线性长度成正比(特点)

头指针和头结点

  • 头结点可有可无,头指针一定存在
  • 头指针始终指向链表的第一个结点。如果存在头结点,那么头指针则指向头结点,头结点的指针指向存储的首结点;如果不存在头结点,那么头指针指向存储的首结点

头结点作用

  • 处理操作方便,将真正的第一个结点的插入、删除与其后结点统一
  • 含头结点的链表无论是否为空都可以将空表与非空表可统一

判空条件

  • 含头结点的单链表判空条件为 L->next == nullptr;
  • 不含头结点的单链表判空条件为 L == nullptr;
  • 含头结点的循环单链表判空条件为 L->next == L;
  • 含头结点循环双链表判空条件 L->next == L && L->prior == L;

单链表操作

头插法

  • 建立单链表时读入数据的顺序和生成链表中的元素是相反的

尾插法

  • 建立单链表时读入数据的顺序和生成链表中的元素是相同的

!头指针指向第一个节点,尾指针指向最后的节点,尾插法最后需将尾指针置空 r->next == nullptr;

插入结点

  1. 查找插入位置 \(i\) 前一位 \((i-1)\)的结点p p = GetElem(L, i - 1);
  2. 结点s的后继指针指向结点p的后继 s->next == p->next;
  3. 结点p的后继指向结点s p->next == s;

时间复杂度

  • 查找第 \(i-1\) 个元素为该算法主要的时间开销,为 \(O(n)\);若结点有指针则时间复杂度仅为 \(O(1)\);若在第 \(i\) 个位置,链表仍需从头访问

静态链表

  • 静态链表使借助数组来描述线性表的链式存储结构
  • 静态链表的存取方式为顺序存取
  • 静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需修改指针
  • 静态链表的指针表示的是下一元素在数组中的位置
  • 静态链表与动态链表相比其缺点有可能浪费较多的存储空间

双链表操作

插入结点

  1. 将插入的结点s连在给定的结点p之后 s->next == p->next;
  2. 将结点p下一个结点的前驱连在结点s上 s->next->proir == s;
  3. 将结点s的前驱连在p上 s->proir == p;
  4. 将结点p的后继连在s上 p->next == s;

!先连右手,再连左手;右手先后继再前驱,左手先前驱在后继;若反向操作则找不到结点p的后继结点

循环链表

循环单链表

  • 最大优点为从任意一结点出发都可以访问到链表中的每一个元素

循环双链表

  • 头结点前驱为尾结点,尾结点后继为头结点,该性质也为****判空条件

E.G.

  • 设一个链表最常用的操作是在末尾插入和删除尾结点,则选用( )最节省时间

[A] 顺序表                                [B] 带尾指针的循环单链表
[C] 循环双链表                        [D] 循环单链表
解:

  • 顺序表在末尾插入和删除时间复杂度为 \(O(n)\);带尾指针的循环单链表在末尾插入是 \(O(1)\),但删除是 \(O(n)\),因为要找到指向该结点的指针;循环单链表在末尾插入和删除都是 \(O(n)\);循环双链表可通过头结点找到尾结点和尾结点的前一个结点,插入和删除都是 \(O(1)\),因此选C

  • 如果最常用的操作是取第n个结点及其前驱,则采用( )最节省时间

[A] 顺序表                                  [B] 带尾指针的循环单链表
[C] 循环双链表                           [D] 循环单链表
解:

  • 顺序存储的最大优点是随机存取,给定序号则时间复杂度为 \(O(1)\),因此选A;链表在访问第n个元素时需要从头开始访问
posted @ 2021-11-02 18:29  絵守辛玥  阅读(103)  评论(0)    收藏  举报