一图胜千言
线性表基本概念
线性表(List):零个或多个数据元素的有限序列。
若将线性表记为(a1, ···, ai-1, ai, ai+1, ···, an),则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1, 2, ···, n-1时,ai有且仅有一个直接后继,当i=2, 3, ···, n时,ai有且仅有一个直接前驱。
线性表顺序存储
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表中的数据元素。
顺序存储-查询
假设每个数据元素占用c个存储单元,那么线性表中第i个数据元素的存储位置:LOC(ai) = LOC(a1) + (i-1)*c
通过这个公式,可以随时算出线性表中任意位置的地址,不管它是第一个还是最后一个,都是相同的时间。因此存取时间复杂度为0(1)。
顺序存储-插入和删除
这边以排队买票为例,模拟中途有人插队或离队的情况:
插入:1. 从最后一个元素开始向前遍历到第i个位置,分别将它们都向后移动一个位置;2. 将要插入元素填入位置i处。
删除:1. 取出删除元素;2. 从删除元素位置开始遍历到最后一个元素位置,分别将它们都向后移动一个位置。
分析得知,插入和删除的时间复杂度为0(n)。
顺序存储-总结
线性表链式存储
链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这些数据元素可以存在内存未被占用的任意位置。
为了表示每个数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。n个结点链成一个链表,即为线性表(a1, ···, ai-1, ai, ai+1, ···, an)的链式存储结构,因为此链表上的每个结点只包含一个指针域,所以叫做单链表。
链式存储-查询
在单链表中,无法知道第i个元素在哪,所以必须从头开始找,直到第i个元素为止。时间复杂度为0(n)。
链式存储-插入和删除
插入:s->next=p->next; p->next=s
删除:q=p->next; p->next=q->next
线性表单链表结构与顺序存储结构对比
经验性结论:
若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。若需要频繁插入和删除时,宜采用单链表结构。
当线性表中的元素个数变化较大或者根本不知道有多大时,最好用单链表结构,这样不需要考虑存储空间的大小问题。而如果事先知道线性表的大致长度,则用顺序存储结构效率会高一些。
循环链表
将单链表中终端结点的指针端由空指针改为指向头结点,就使得整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表。
双向循环链表
双向链表是在循环链表的每个结点中,再设置一个指向其前驱结点的指针域。