线性表
顺序表
优点
- 逻辑上相邻元素的物理位置一定相邻
- 随机存取(时间复杂度为 \(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;
插入结点
- 查找插入位置 \(i\) 前一位 \((i-1)\)的结点p
p = GetElem(L, i - 1); - 结点s的后继指针指向结点p的后继
s->next == p->next; - 结点p的后继指向结点s
p->next == s;
时间复杂度
- 查找第 \(i-1\) 个元素为该算法主要的时间开销,为 \(O(n)\);若结点有指针则时间复杂度仅为 \(O(1)\);若在第 \(i\) 个位置,链表仍需从头访问
静态链表
- 静态链表使借助数组来描述线性表的链式存储结构
- 静态链表的存取方式为顺序存取
- 静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需修改指针
- 静态链表的指针表示的是下一元素在数组中的位置
- 静态链表与动态链表相比其缺点是有可能浪费较多的存储空间
双链表操作
插入结点
- 将插入的结点s连在给定的结点p之后
s->next == p->next; - 将结点p下一个结点的前驱连在结点s上
s->next->proir == s; - 将结点s的前驱连在p上
s->proir == p; - 将结点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个元素时需要从头开始访问

浙公网安备 33010602011771号