线性表(List):零个或多个数据元素(类型相同)的有限序列.
线性表中,相连的两个元素A1,A2.A1叫做A2的直接前驱元素,A2叫做A1的直接后继元素.一个元素有且只有一个直接前驱元素或直接后继元素.
线性表元素的个数n(n>=0)定义为线性表的长度,当n=0的时,成为空表.
元素在线性表中的位置称为位序.
在复杂的线性表中,一个数据元素可以由若干个数据项组成.
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素.
可以用一维数组来实现顺序存储结构(三个重要属性):
1.存储空间的起始位置:数组data,存储位置就是存储空间的存储位置。
2.线性表的最大存储容量:数组长度MaxSize。
3.线性表的当前长度length。
数组的长度是存放线性表的存储空间的长度
线性表的长度是线性表中数据元素的个数。
存储器中的每个存储单元都有自己的编号,这个编号称为地址。
通过一个数据元素的存储位置,和每个数据元素占据的单位空间,可以推算出另一个数据元素的地址。时间复杂度都是O(1)
具有时间复杂度都是O(1)这一特点的存储结构称为随机存取结构。
插入算法的思路:
1.如果插入位置不合理,抛出异常。
2.如果线性表长度大于等于数组长度,则抛出异常或动态增加容量。
3.从最后一个元素开始向前遍历到第i个元素,分别将他们后移一个位置。
4.将要插入元素插入位置i处。
5.表长加1。
删除算法的思路:
1.如果删除位置不合理,抛出异常。
2.取出删除元素。
3.从删除元素位置开始遍历到最后一个元素为止,分别将他们都向前移动一个位置。
4.表长减1。
线性表的优点:
1.无须为表示表中元素之间的逻辑关系而增加额外的存储空间。
2.可以快速地存取表中任一位置的元素。
线性表的缺点:
1.插入和删除操作需要移动大量元素。
2.当线性表长度变化较大时,难以确定存储空间的容量。
3.造成存储空间的“碎片”。
为了表示每个数据元素ai与其直接后继数据元素 ai+1之间的逻辑关系,对数据元素 ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称作指针或链。这两部分信息组成元素 ai的存储映像,称为结点(Node)。
结点由存放数据元素的数据的数据域和存放后继结点地址的指针域组成。
n个结点 (ai的存储映像)链结成一个链表,即为线性表的链式存储结构,因为此链表的每个节点中只包含一个指针域,所以叫做单链表。
链表中第一个结点的存储位置叫做头指针。
为了方便操作,有时会在单链表的第一个结点前附设一个结点,称为头结点。头结点的数据域可以不存储信息,也可以存储表的附加信息。
{可存线性表部分数据丨【头指针】指向第一个节点数据}---{【第一个结点数据】丨指向第二个结点}-..-{【第N个结点数据】|【尾指针】指向空}
---------------------------(可考虑为)a-1------------------------------------------------------a0------------------------------------------------------an---------------------------
头指针与头结点的区别:
1.头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。而头结点是为了操作的统一和方便而设立的,放在第一元素的节点之前,其数据域一般无意义。
2.头指针具有标识作用,所以常用头指针冠以链表的名字。而头结点的存在对在第一元素的结点前插入结点和删除第一结点,其操作与其他节点的操作就统一。
3.不论链表是否为空,头指针均不为空。头指针是链表的必要元素,而头结点不一定是链表必要元素。
空表的头结点的指针域为空。
假设p是指向线性表第 i 个元素的指针,则该结点ai的数据域可以用 p -> data 表示,则该结点ai的指针域可以用 p -> next 表示。
单链表的读取核心思想为“工作指针后移”。
要获取一个单链表中的第 i 个元素,初始化声明一个 j = 1,声明一个结点指向链表的第一个结点。不断指向下一结点,j 递增。若到表尾,指为空或 j > i 则查找失败,若 j = i 则查找成功。
单链表的插入
先查找,确认是否存在,然后将插入结点指针指向插入位置后个结点的数据域,再改变前个结点的指针域指向插入结点的数据域。
单链表的删除
先查找,确认元素是否存在,然后将删除元素前一个元素的指针指向后一个元素的数据域,释放删除元素。
对于插入或删除数据越频繁的操作,单链表的效率优势就越明显。
单链表结构与顺序存储结构优缺点对比:
存储分配方式:顺序存储结构用一段连续的存储单元依次存储线性表的数据元素,而单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。
时间性能:查找 顺序(O(1)),单链表(O(n))。插入删除 顺序平均移动表长一半(O(n)),单链表(O(n))。单链表插入删除时间仅为O(1)。
空间性能:顺序存储结构需要预分配存储空间,空间分配过大造成浪费,空间分配过小造成溢出。单链表不需要分配存储空间,元素个数无限制。
数组表示的链表叫做静态链表(游标实现法)。
优点:插入删除时,只需要该表游标。
缺点:没有解决连续存储分配带来的表长难以确定的问题,失去了随机存取的特性。
循环链表:单链表中终端节点的指针端由空指针改为指向头结点,这种头尾相接的单链表称为单循环链表,简称循环链表。
双向链表:单链表中的每个结点中,再设置一个指向其前驱结点的指针域。