线性表的特点是,在数据元素的非空有限集合,存在唯一一个“第一个”和唯一一个“最后一个”的元素;除第一个元素,每个元素只有一个前驱;除最后一个元素,每个元素只有一个后继元素
线性表的顺序表示指一组地址连续的存储单元依次存储线性表的数据元素,线性表元素的存储位置满足
LOC(ai+1) = LOC(ai)+l,l为一个元素的存储单元
即一般来说,线性表的第i个数据元素ai的存储位置为
LOC(ai) = LOC(a1)+(i-1)*l,其中a1为基地址
线性表的这种机内表示称做线性表的顺序存储结构,反之,称这种存储结构的线性表为顺序表
顺序表的插入与删除,都需要移动元素,移动元素的个数取决于插入或删除的元素的位置,时间复杂度为O(n)
假如需要对线性表表示集合并进行集合的各种运算,应先对表中元素进行排序。
线性表的链式存储结构是一组任意的存储单元存储线性表的数据元素(这组存储单元可以连续,也可以不连续)。为了表示某个数据元素ai和ai+1的逻辑关系,我们需要对数据元素ai存储本身信息之外,还要存储一个指示其后继的信息。存储数据元素信息的域称为数据域,存储后继存储位置的域称为指针域。两个域组成ai的存储映象,称为结点。
n(1=<n=<i)个结点即为一个链表
每个链表都有一个头结点,头结点的数据域可以不存储任何信息,也可以存储链表的长度等信息。
由于链表在物理位置上存储位置可能不连续,我们无法通过下标索引,但是我们可以通过遍历的方式
如图所示,遍历的时间取决于i的大小,所以时间复杂度为O(n)
如果我们要实现插入操作应该怎么办,假设需要一个要插入的结点x,插入在a结点之后,操作是
先寻找到a,再让
x->next = a->next, a->next = x;
同样我们如果需要删除第i个元素,首先我们要找个第i个元素,并设置s指向其前驱,
设置q为第i个元素,则两者有这样的关系 s->next == q
要删除q,则需要s->next = q->next;即先让s的后继指向q的后继,再free(q)
两者复杂度都为O(n),因为主要耗时操作都在寻找i-1个元素。
如果要归并两个链表,则像之前的顺序表一样,但是不需要再创建另外的的结点空间,即空间复杂度不同