线性表的链式存储结构及其运算
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2
2.3.1 线性链表
链表是指用一组任意的存储单元来依次存放线性 表的结点,
特点:这组存储单元即可以是连续的,也可以是 不连续的,甚至是零散分布在内存中的任意位置 上的。链表中结点的逻辑次序和物理次序不一定 相同。
为了能正确表示结点间的逻辑关系,在存储每 个结点值的同时,还必须存储指示其后继结点的 地址(或位置)信息,这个信息称为指针 (pointer)或链(link)。这两部分组成了链表中 的结点结构:
2.3 线性表的链式存储结构及其运算
一、单链表的存储结构 二、 单 链表的操作实现 三、链表的运算效率分析
1
2.3 线性表的链式表示和实现
线性表的顺序表示的特点是用物理位置上的 邻接关系来表示结点间的逻辑关系,这一特点 使我们可以随机存取表中的任一结点,但它也 使得插入和删除操作会移动大量的结点.为避免 大量结点的移动,我们介绍线性表的另一种存 储方式, 链式存储结构,简称为链表(Linked List)。
head
a1
循环链表示意图: head
a2
……
an
8
4)头指针、头结点和首元结点的区别 示意图如下:
head
info
a1
a2
…
an ^
头指针 头结点 首元结点
头指针是指向链表中第一个结点(或为头结点、或为首元 结点)的指针;
头结点是在链表的首元结点之前附设的一个结点;数据域 内只放空表标志和表长等信息,它不计入表长度。
6
链表存放示意图如下:
head
a1
a2
……
an /\
例:请画出26个英文字母表的链式存储结构。 解:该字母表的逻辑结构为:( a, b, … ,y, z)
该字母表在内存中链式存放的样式举例如下:
讨论1 :每个存储结点都包含两部分:数据域和 指针域(链域) 。 讨论2:在单链表中,除了首元结点外,任一结点的存储位置
node.data='a';node.next=q
方式2:p指向结点首地址,然后 p->data='a'; p->next=q;
方式3: p指向结点首地址,然后 (*p).data='a'; (*p).next=q
11
上例链表的逻辑结构示意图有以下两种形式:
①
H
ZHAO
QIAN
SUN
LI
ZHOU
②
H
WU ZHAO
ZHENG
WANG /\
QIAN
SUN
LI
ZHOU
WU
ZHENG
WANG /\
区别:① 无头结点 ② 有头结点
头结点不计入 链表长度!
12
对比带头结点的单链表的插入、删除过程和 不带带头结点的单链表的插入、删除过程,可以 得知:
data link
3
其中:data域是数据域,用来存放结点的值。 next是指针域(亦称链域),用来存放结点的直接 后继的地址(或位置)。
链表正是通过每个结点的链域将线性表的n个结 点按其逻辑次序链接在一起的。由于上述链表的每 一个结只有一个链域,故将这种链表称为单链表 (Single Linked)。
答:无头结点时,当头指针的值为空时表示空表; 有头结点时,当头结点的指针域为空时表示空表。
头指针
头指针 头结点
^
^
ห้องสมุดไป่ตู้无头结点
有头结点
头结点不计入链 表长度!
10
2、带头结点单链表和不带头结点单链表的比较 例: 一个线性表的逻辑结构为:
(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG),其 存储结构用单链表表示如下,请问其头指针的值是多少?
由 其直接前驱结点的链域的值 指示。
7
(2) 与链式存储有关的术语:
1)结点:数据元素的存储映像。由数据域和指针域两部分组成;
2)链表: n 个结点由指针链组成一个链表。它是线性表的链式 存储映像,称为线性表的链式存储结构。
3)单链表、双链表、多链表、循环链表: • 结点只有一个指针域的链表,称为单链表或线性链表; • 有两个指针域的链表,称为双链表(但未必是双向链表); • 有多个指针域的链表,称为多链表; • 首尾相接的链表称为循环链表。
4
一、 单链表的存储结构
1、单链式及表示方法 (1)单链表:构成链表的结点只有一个指向直接后继结点 的指针。其结构特点:逻辑上相邻的数据元素在物理上 不一定相邻。 如何实现? 通过指针来实现! 让每个存储结点都包含两部分:数据域和指针域
样式: 数据域 指针域 或 data next
数据域:存储 元素数值数据
答:因每个结点至少有两个分量,且数据类型通常不一致,所 以要采用结构数据类型。
以26个字母的链表为例,每个结点都有两个分量:
字符型 指针型 p ‘a’
q ‘b’
p
data *next 设每个结点用变量node表示,其指
针用p表示,两个分量分别用data和
node
*next表示,这两个分量如何赋值?
方式1: 直接表示为
存储地址 1 7 13 19 25 31 37 43
数据域 LI
QIAN SUN WANG WU ZHAO ZHENG ZHOU
指针域 43 13 1
NULL 37 7 19 25
答:头指针是指向链 表中第一个结点的指 针,因此关键是要寻 找第一个结点的地址。
H
31
ZHAO 7
称:头指针H的值是31
若设计的单链表带头结点,则无论是在第一 个数据元素结点前插入还是在其他数据元素结点 前插入都不会改变头指针的数值。
若设计的单链表不带头结点,则在第一个数据 元素结点前插入与在其他数据元素结点前插入其 算法的处理方法不同。在单链表中删除一个结点 时类似。因此,单链表一般构造成带头结点的单 链表。
13
讨论: 链表的数据元素有两个域,不再是简单数据类 型,编程时该如何表示?
指针域:存储直接后继的 存储位置
设计思想:牺牲空间效率换取时间效率
5
定义单链表结点的结构体如下: typedef struct Node {
DataType data; struct Node *next; }SLNode; 其中,data域用来存放数据元素,next域用来存放指向下 一个结点的指针。
首元结点是指链表中存储线性表第一个数据元素a0的结点。
9
讨论1. 在链表中设置头结点有什么好处?
答:头结点即在链表的首元结点之前附设的一个结点,该结
点的数据域可以为空,也可存放表长度等附加信息,其作用是 为了对链表进行操作时,可以对空表、非空表的情况以及对首 元结点进行统一处理,编程更方便。
讨论2. 如何表示空表?
2.3.1 线性链表
链表是指用一组任意的存储单元来依次存放线性 表的结点,
特点:这组存储单元即可以是连续的,也可以是 不连续的,甚至是零散分布在内存中的任意位置 上的。链表中结点的逻辑次序和物理次序不一定 相同。
为了能正确表示结点间的逻辑关系,在存储每 个结点值的同时,还必须存储指示其后继结点的 地址(或位置)信息,这个信息称为指针 (pointer)或链(link)。这两部分组成了链表中 的结点结构:
2.3 线性表的链式存储结构及其运算
一、单链表的存储结构 二、 单 链表的操作实现 三、链表的运算效率分析
1
2.3 线性表的链式表示和实现
线性表的顺序表示的特点是用物理位置上的 邻接关系来表示结点间的逻辑关系,这一特点 使我们可以随机存取表中的任一结点,但它也 使得插入和删除操作会移动大量的结点.为避免 大量结点的移动,我们介绍线性表的另一种存 储方式, 链式存储结构,简称为链表(Linked List)。
head
a1
循环链表示意图: head
a2
……
an
8
4)头指针、头结点和首元结点的区别 示意图如下:
head
info
a1
a2
…
an ^
头指针 头结点 首元结点
头指针是指向链表中第一个结点(或为头结点、或为首元 结点)的指针;
头结点是在链表的首元结点之前附设的一个结点;数据域 内只放空表标志和表长等信息,它不计入表长度。
6
链表存放示意图如下:
head
a1
a2
……
an /\
例:请画出26个英文字母表的链式存储结构。 解:该字母表的逻辑结构为:( a, b, … ,y, z)
该字母表在内存中链式存放的样式举例如下:
讨论1 :每个存储结点都包含两部分:数据域和 指针域(链域) 。 讨论2:在单链表中,除了首元结点外,任一结点的存储位置
node.data='a';node.next=q
方式2:p指向结点首地址,然后 p->data='a'; p->next=q;
方式3: p指向结点首地址,然后 (*p).data='a'; (*p).next=q
11
上例链表的逻辑结构示意图有以下两种形式:
①
H
ZHAO
QIAN
SUN
LI
ZHOU
②
H
WU ZHAO
ZHENG
WANG /\
QIAN
SUN
LI
ZHOU
WU
ZHENG
WANG /\
区别:① 无头结点 ② 有头结点
头结点不计入 链表长度!
12
对比带头结点的单链表的插入、删除过程和 不带带头结点的单链表的插入、删除过程,可以 得知:
data link
3
其中:data域是数据域,用来存放结点的值。 next是指针域(亦称链域),用来存放结点的直接 后继的地址(或位置)。
链表正是通过每个结点的链域将线性表的n个结 点按其逻辑次序链接在一起的。由于上述链表的每 一个结只有一个链域,故将这种链表称为单链表 (Single Linked)。
答:无头结点时,当头指针的值为空时表示空表; 有头结点时,当头结点的指针域为空时表示空表。
头指针
头指针 头结点
^
^
ห้องสมุดไป่ตู้无头结点
有头结点
头结点不计入链 表长度!
10
2、带头结点单链表和不带头结点单链表的比较 例: 一个线性表的逻辑结构为:
(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG),其 存储结构用单链表表示如下,请问其头指针的值是多少?
由 其直接前驱结点的链域的值 指示。
7
(2) 与链式存储有关的术语:
1)结点:数据元素的存储映像。由数据域和指针域两部分组成;
2)链表: n 个结点由指针链组成一个链表。它是线性表的链式 存储映像,称为线性表的链式存储结构。
3)单链表、双链表、多链表、循环链表: • 结点只有一个指针域的链表,称为单链表或线性链表; • 有两个指针域的链表,称为双链表(但未必是双向链表); • 有多个指针域的链表,称为多链表; • 首尾相接的链表称为循环链表。
4
一、 单链表的存储结构
1、单链式及表示方法 (1)单链表:构成链表的结点只有一个指向直接后继结点 的指针。其结构特点:逻辑上相邻的数据元素在物理上 不一定相邻。 如何实现? 通过指针来实现! 让每个存储结点都包含两部分:数据域和指针域
样式: 数据域 指针域 或 data next
数据域:存储 元素数值数据
答:因每个结点至少有两个分量,且数据类型通常不一致,所 以要采用结构数据类型。
以26个字母的链表为例,每个结点都有两个分量:
字符型 指针型 p ‘a’
q ‘b’
p
data *next 设每个结点用变量node表示,其指
针用p表示,两个分量分别用data和
node
*next表示,这两个分量如何赋值?
方式1: 直接表示为
存储地址 1 7 13 19 25 31 37 43
数据域 LI
QIAN SUN WANG WU ZHAO ZHENG ZHOU
指针域 43 13 1
NULL 37 7 19 25
答:头指针是指向链 表中第一个结点的指 针,因此关键是要寻 找第一个结点的地址。
H
31
ZHAO 7
称:头指针H的值是31
若设计的单链表带头结点,则无论是在第一 个数据元素结点前插入还是在其他数据元素结点 前插入都不会改变头指针的数值。
若设计的单链表不带头结点,则在第一个数据 元素结点前插入与在其他数据元素结点前插入其 算法的处理方法不同。在单链表中删除一个结点 时类似。因此,单链表一般构造成带头结点的单 链表。
13
讨论: 链表的数据元素有两个域,不再是简单数据类 型,编程时该如何表示?
指针域:存储直接后继的 存储位置
设计思想:牺牲空间效率换取时间效率
5
定义单链表结点的结构体如下: typedef struct Node {
DataType data; struct Node *next; }SLNode; 其中,data域用来存放数据元素,next域用来存放指向下 一个结点的指针。
首元结点是指链表中存储线性表第一个数据元素a0的结点。
9
讨论1. 在链表中设置头结点有什么好处?
答:头结点即在链表的首元结点之前附设的一个结点,该结
点的数据域可以为空,也可存放表长度等附加信息,其作用是 为了对链表进行操作时,可以对空表、非空表的情况以及对首 元结点进行统一处理,编程更方便。
讨论2. 如何表示空表?