线性表概述
特点
在数据元素的非空有限集中
- 存在唯一一个被称为“第一个”的数据元素
- 存在唯一一个被称为“最后一个”的数据元素
- 除了第一个元素之外,每个元素只有唯一一个直接前驱元素
- 除了最后一个元素之外,每个元素只有唯一一个直接后继元素
简称:四个唯一
线性表的定义
n个数据元素的有限序列。当n=0时,称为空表,n!=0时,ai 是第 i 个数据元素,i 称为位序。
两表合并问题
若LA、LB两表长度分别为m、n,要求将存在于LB不存在LA中的元素添加到LA后面。
这个情况需要将LA表中的每一个数据元素都和LB比较,因此时间复杂度为O(m*n)
若LA、LB两表长度分别为m、n,并且有序,要求归并LA、LB两表。
思路,建立一个LC表,用两个指针分别指向LA、LB表,比较插入到LC中。是时间复杂度为O(m+n),如果LA、LB是用链式存储,则直接修改指针指向就好了。
可以看出,如果用线性表表示集合并进行集合的各种运算,应先对表中元素及进行排序。
线性表的表示与实现
线性表的顺序表示与实现
线性表的顺序指的是用一组地址连续的存储单元依次存储线性表的数据元素。这种存储结构的线性表称为顺序表。顺序表的特点是以物理位置上的相邻表示逻辑上的相邻,存储密度高,因此只要确定了线性表的起始位置,线性表中的任一元素都可以访问。但是插入和删除的时间复杂度为O(n)。
线性表的链式表示与实现
顺序表的优点恰恰是它的缺点,因为顺序表元素存储需要占用一大块连续内存,长此以往,将造成很多内存碎片;并且它的插入删除时间复杂度高。基于这些问题,提出链式存储。
单链表
单链表每个结点除了存储线性表中的元素之外,还需要存储指向下一结点的指针,因此使用这种方式存储数据元素可以不使用连续内存。存储线性表元素的位置称为数据域,存储指针的位置称为指针域。
单链表中使用头指针指向链表中第一个结点,如果单链表中存储头结点,那么头结点指向链表第一个结点,头指针指向头结点。头结点的数据域通常不存储东西或者存储此链表的长度。最后一个结点称为尾结点,指针域为NULL。
链式存储的插入删除复杂度为O(n),因为需要耗费大量时间寻找插入/删除元素的位置。并且链式存储不能随机访问线性表元素,除非有指针指向。如果是插入/删除某一指针指向的线性表中元素,那么插入/删除的时间复杂度为O(1)。
静态链表
静态链表是用数组来实现链表的结构,首先分配一块地址连续的数组,每个数组元素类似于单链表的结点,由数据域和指针域构成,数据域存储数据,指针域存储数组下标。静态链表中的“指针”域称为游标。静态链表通常用于不存在“指针”的高级语言中。
循环链表
循环链表指的是在单链表的基础上,尾结点的指针域中存储的是指向第一个结点(或者头结点)的指针。循环链表有时候不设置头指针,而是设置一个尾指针,为什么呢?第一:根据尾指针可以找到第一个结点,而且时间复杂度为O(1)。第二:使用尾指针在某些场合下更为方便,比如将一个链表添加到另外一个链表尾部。
双向链表
双向链表的每个结点包含一个数据域和两个指针域,两个指针域分别为prior指针和next指针,prior指向该结点的前一个结点,next指向该结点的后一个结点。头结点的prior域指向尾结点,尾结点的next域指向头结点。
引出双向链表的原因是便于找到结点的前驱结点。另外注意在双向链表的插入和删除操作中prior和next指针域都要修改。
一元多项式的存储
比如:3+4x+5x2+6x3
方法一:只存储系数,然后指数默认。比如用一个数组存储,a[0]存储x0的系数,a[1]存储x1的系数,………………
这种方式有很大问题,比如存储下面这个
x99+x199+x1999
方法二:存储系数和指数。这种方式在某些情况下节省空间
参考资料
严蔚敏《数据结构》
王道数据结构单科书