线性表(List):零个或多个数据元素的有限序列。
线性表的顺序存储结构:
用一段地址连续的存储单元依次存储线性表的数据元素。
描述顺序存储结构的三个属性:
(1)存储空间的起始位置
(2)线性表的最大容量
(3)线性表的当前长度
线性表的链式存储结构:
为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素的域称为数据域,把存储直接后继位置的域称为指针域,指针域中存储的信息称作指针或链,这两部分信息组成数据元素ai的存储映像,称为结点。n个结点链结成一个链表,即为线性表的链式存储结构。因为此链表的每个结点只包含一个指针域,所以叫做单链表。
头指针:指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。头指针具有标识作用,所以常用头指针冠以链表的名字,无论链表是否为空,头指针均不为空。头指针是链表的必要元素。
头结点:为了操作的统一和方便而设立,放在第一元素的结点之前,其数据域一般无意义,有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其他结点的操作就统一了,头结点不一定是链表的必要元素。
单链表的读取:(获取链表的第i个数据)
(1)声明一个结点p指向链表的第一个结点,初始化j从1开始
(2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
(3)若到链表末尾p为空,则说明第i个元素不存在
(4)否则查找成功,返回结点p的数据。
单链表的插入:
假设存储元素e的结点为s,要实现结点p,p->next和s之间的逻辑关系的变化,只需将结点s插入到结点p和p->之间即可,不用惊动其他结点,只需要让s->next和p->next的指针做一点改变即可。就是将p的后继结点改成s的后继结点,再把结点s变成p的后继结点
(1)声明一结点p指向链接第一个结点,初始化j从1开始
(2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
(3)若到链表末尾p为空,则说明第i个元素不存在
(4)否则查找成功,在系统中生成一个空节点s
(5)将数据元素e赋值给s->data
(6)单链表的插入标准语句s->next=p->next;p->next=s
(7)返回成功
单链表的删除:
设存储元素ai的结点为q,要实现将结点q删除单链表的操作,其实就是将他的前继结点的指针绕过,指向它的后继结点即可
(1)声明一结点p指向链接第一个结点,初始化j从1开始
(2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一个结点,j累加1
(3)若到链表末尾p为空,则说明第i个元素不存在
(4)否则查找成功,将欲删除的结点p->赋值给q
(5)单链表的删除标准语句p->next=q->next
(6)将q结点中的数据赋值给e,作为返回
(7)将q结点释放
(8)返回成功
单链表的整表创建
(1)声明一结点p和计数器变量i
(2)初始化一空链表L
(3)让L的头结点的指针指针指向NULL,即建立一个带头结点的单链表
(4)循环:生成一新结点赋值给p;随机生成一数字赋值给p的数据域p->data;将p插入到头结点与前一新结点之间
单链表的整表删除:
(1)声明一结点p和q
(2)释放p
(3)循环:将下一结点赋值给q;释放p;将q赋值给p
单链表结构和顺序结构的对比结论:
(1)若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。若需要频繁插入和删除时,宜采用单链表结构。
(2)当线性表中的元素个数变化较大或者根本不知道有多大时,最好采用单链表结构,这样可以不需要考虑存储空间的大小问题,而如果事先知道线性表的大致长度,用顺序结构效率会高很多。