第二章:线性表
基本概念:
线性结构的特点:(在数据元素的非空有限集中):
1/存在唯一的一个被称作“第一个”的数据元素;
2/存在唯一的一个被称作“最后一个”的数据元素;
3/除第一个之外,集合中的每个数据元素均只有一个前驱;
4/除最后一个之外,集合中每个数据元素均只有一个后继
线性表的类型定义:
线性表:一个线性表是n个数据元素的有限序列。
在稍微复杂的线性表中,一个数据元素可以由若干个数据项组成。在这种情况下,常把数据元素称为记录,含有大量记录的线性表又称为文件。
所以,我们得出线性表的特点:
1/表中元素的个数有限。
2/表中元素具有逻辑上的顺序性,表中元素有其先后次序。
3/表中元素都是数据元素,每个元素都是单个元素。
4/表中元素的数据类型都相同,这意味着每个元素占有相同大小的存储空间
线性表的顺序表示和实现:
线性表的顺序表示称做线性表的顺序存储结构或顺序映像,通常称这种存储结构的线性表为顺序表。
一、顺序表:它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。
特点:
1/逻辑顺序和物理顺序相同。
2/线性表中元素的位序是从1开始的,而数组中元素的下标是从0开始的。
3/只要确定了存储线性表的起始位置,线性表中任一数据元素都可以随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。(即通过首地址和元素序号可在时间O(1)内找到指定的元素)
4/顺序表的存储密度高,每个结点只存储数据元素。
5/顺序表的插入和删除需要移动大量元素。(插入:插入位置以后整体元素后移;删除:删除位置以后整体元素前移)
插入操作平均时间复杂度:O(n) 平均次数:n/2
删除操作平均时间复杂度:O(n) 平均次数:(n-1)/2
查找操作平均时间复杂度:O(n) 平均次数:(n+1)/2
静态分配:数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据将会产生溢出,进而导致程序崩溃。
动态分配:存储数组的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数据空间占满,就会另外开辟一块个更大的存储空间,用以替换原来的存储空间。
线性表的链式表示和实现:
顺序存储结构的弱点:在插入或删除时需要移动大量元素。
因此引入另一种表示方法——链式存储结构,它不要求逻辑上相邻的元素在物理位置上也相邻,因此它插入和删除不需要移动大量元素,只需要修改指针,但同时失去了顺序表随机存取的优点。
线性表的链式存储结构的特点是:
1/用一组任意的存储单元存储线性表的数据元素。
2/为建立数据元素之间的线性关系,对每个链表结点,存放元素自身的信息。(存储数据元素信息的域称为数据域)
3/还要存放一个指向其后继的指针。(存储直接后继存储位置的域称为指针域,指针域中存储的信息称为指针或链)
4/n个结点链接成一个链表,即为线性表的链式存储结构。
二、单链表:
单链表的特点:
1/又因为链表中的每个结点只包含一个指针域,又称线性链表或单链表。
2/整个链表必须从头指针开始进行,头指针指示链表中第一个结点的存储位置。(头指针为NULL时表示一个空表)
3/由于最后一个数据元素没有直接后继,所以最后一个节点的指针为“空”,(NULL)。
4/线性链表表示线性表时,数据元素之间的逻辑关系是由结点中的指针指示的。指针为数据元素之间的逻辑关系映像。(即逻辑上相邻的数据元素,存储的物理位置上不一定相邻)
5/这种存储结构为非顺序映像或链式映像。
单链表的优缺点:
1/单链表可以解决需要大量连续存储单元的缺点,但由于附带指针域,存在浪费存储空间的缺点。
2/由于单链表的元素离散地分布在存储空间中,所以单链表是非随机存取的存储结构。(即不能直接找到表中某个特定的结点)
3/查找某个特定的结点时,需要从表头开始遍历,依次查找。
4/为操作上的方便,在单链表第一个结点之前附加一个结点,称为头结点。(头结点的数据域通常不设任何信息,但也可以记录表长等信息)
5/头结点的指针域始终指向线性表的第一个元素结点。
1/头插法:采用头插法建立单链表时,读入数据的顺序与生成的链表中的元素的顺序是相反的。每个结点插入的时间为O(1),设单链表长为n,则总时间复杂度为O(n)。
2/尾插法:结点次序和输入数据的顺序一致。增加尾指针,使其始终指向当前链表的尾结点。时间复杂度和头插法相同。
3/按序号查找结点值:从第一个结点出发,顺着指针的next域逐个往下搜索,直到找到为止,否则返回最后一个结点指针域NULL。时间复杂度为O(n)
4/按值查找表结点:从第一个结点出发,由前往后依次比较表中各结点数据域的值,若某结点数据域的值等于给定值,则返回该结点的指针,若单链表中没有这样的结点,返回NULL。
5/插入结点操作:将值为x的新结点插入第i个位置上时,要找到第i-1个结点,在其后插入新结点。主要时间开销在于查找第i-1个元素,时间复杂度为O(n)
6/删除结点操作:将第i个结点删除,就要找到第i-1个结点,将第i-1个结点的指针域存放的地址改变为第i+1的地址,再将第i个结点删除,同样,该算法的时间也是花在了查找操作上,时间复杂度为O(n)。
7/求表长操作:即计算单链表中数据结点的个数,(遍历)设置计数器,每访问一个结点加一,直到访问到空为止。时间复杂度为O(n)