2.1.1 引子:多项式表示
多项式表示问题的启示:
1.同一个问题可以有不同的表示(存储)方法
2.有一类共性问题:有序线性序列的组织和管理
2.1.2 线性表及其顺序存储
“ 线性表(Linear List)” :由同类型数据元素构成有序序列的线性结构
- 表中元素个数称为线性表的长度
- 线性表没有元素时,称为空表
- 表启示位置称表头,表结束位置称表尾
线性表的抽象数据类型描述
类型名称:线性表(List)
数据对象集:线性表是n(n>=0)个元素构成的有序序列(a1,a2,……,an)
操作集:线性表L∈ List,整数i表示位置,元素X∈ ElementType,线性表基本操作主要有:
1.List MakeEmpty():初始化一个空线性表L;
2.ElementType FindKth(int K,List L):根据位序K,返回相应元素;
3.int Find(ElementType X,List L):在线性表L中查找X的第一次出现位置;
4.void Insert(ElementType X,int i,List L):在位序i前插入一个新元素X;
5.void Delete(int i,List L):删除指定位序i的元素;
6.int Length(List L):返回线性表L的长度n.
线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各元素
线性表中的按值查找是指在线性表中查找与给定值 x 相等的数据元素。在顺序表中完成该运算最简单的办法是:从第一个元素 a1 起依次和 x 比较,直到找到一个与 x 相等的数据元素,则返回它在顺序表中的存储下标;或者查遍整个表都没有找到与 x 相等的元素,返回 -1。
本算法的主要运算是比较。显然比较的次数与 x 在表中的位置有关,也与表长有关,当 a1= x 时,比较一次成功,当an = x 时比较 n 次成功。平均比较次数为 (n+1)/2 ,时间复杂度为 O(n)。
线性表的插入是指在表的第 i 个位置上插入一个值为 x 的新元素,插入后使原表长为 n 的表(a1,a2,a3,…,ai-1,ai,ai+1,…,an)成为表长为 n+1 的表(a1,a2,a3,…,ai-1,x,ai,ai+1,…,an+1)。i的取值范围为 1 <= i <= n+1。
在顺序表上完成这一运算需通过以下步骤进行:
(1).将 ai ~ an 顺序向后移动,为新元素让出位置;
(2).将 x 置入空出的第 i 个位置;
(3).修改 last 指针(即修改表长),是指仍指向最后一个元素。
本算法注意以下问题:
(1).顺序表中数据区域有 MAXSIZE 个存储单元,所以在向顺序表中做插入时先检查表空间是否满了。在表满的情况下不能再做插入,否则将产生溢出错误;
(2).要检验插入位置的有效性,这里 i 的有效范围是 :1 <= i <= n+1,其中 n 为原表长;
(3).注意数据的移动方向。
插入算法的时间性能分析如下:
顺序表上的插入运算,时间主要消耗在数据的移动上,在第 i 个位置插入 x ,从 ai 到 an 都要向后移动一个位置,共需要移动 n-i+1 个元素,而 i 的取值范围为:1 <= i <= n+1 ,即有 n+1 个位置可以插入。设在第 i 个位置上作插入的概率为 Pi,则平均移动数据元素的次数:
Ein=∑n+1i=1pi(n-i+1)
设:Pi=1/(n+1),即在任一位置插入概率相等的情况下,则:
Ein=∑n+1i=1pi(n-i+1)=1/(n+1)∑n+1i=1(n-i+1)=n/2
(∑是一个求和符号,下标表示从第几个数开始求和,一般用i=1表示,上标表示加到第几个数,一般用n表示。 如果下标是i=1, 上标是n,就表示从第一个数加到第n个数。)
这表明在顺序表上做插入操作需移动表中一半的数据元素,时间复杂度为O(n)。
线性表的删除是指将表中第 i 个元素从线性表中去掉,删除后使原表长为 n 的线性表( a1,a2,a3,…,ai-1,ai,ai+1,…,an ) 成为表长为 n-1 的线性表(a1,a2,a3,…,ai-1,ai+1,…,an)。i 的取值范围为:1 <= i <= n。
顺序表完成这一运算的步骤如下:
(1)将 ai+1 ~ an 顺序向前移动;
(2) 修改 last 指针(即修改表长)使之仍指向最后一个元素。
本算法应注意以下问题:
(1)删除第 i 个元素, i 的取值为 1 <= i <= n,否则第 i 个元素不存在,因此,要检查删除位置的有效性;
(2)当表空时不能做删除,因表空时 L -> last 的值为 -1,条件 “ i < 1 || i > L -> last +1 ” 也包括了对表空的检查;
(3)删除 ai 之后,该数据已不存在,如果需要,先取出 ai ,再做删除。
删除算法的时间性能分析如下:
与插入运算相同,其时间主要消耗在了移动表中元素上,删除第 i 个元素时,其后面的元素 ai+1 ~ an 都要向前移动一个位置,共移动了 n - i 个元素,所以平均移动数据元素的次数:
Ede=∑n+1i=1pi(n-i)
设:Pi=1/n,即在任一位置插入概率相等的情况下,则:
Ede=∑n+1i=1pi(n-i)=1/n∑n+1i=1(n-i)=(n-1)/2
2.1.3 线性表的链式存储实现及查找
不要求逻辑上相邻的两个元素物理上也相邻:通过“链”建立起数据元素之间的逻辑关系。
- 插入、删除不需要移动数据元素,只需要修改“链”。
在数组里面,我们要找到已知序号的元素是很简单的,而通过 Las t指针也可以很快求出线性表的长度;但是如果在一个链表里面,我们光知道一个链表的头,我们怎么知道第 i 个元素在哪里?链表的长度在哪里?所以与数组相比,链式存储的结构在这两个问题上面就会复杂了。