武汉理工大学 信息工程学院 数据结构 ppt 课件ch02_2 线性表2-链式表示和实现
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Status ListInsert(LinkList &L, int i, ElemType e) {p=L->next; j=1; while(p&&j<i-1){p=p->next; ++j;} i if(!p||j>i-1)return ERROR; S=(LinkList)malloc(sizeof(Lnode)); S->data=x; S->next=p->next; P->next=s; return OK;}
typedef struct Lnode { ElemType data; struct Lnode *next; }Lnode, *LinkList; //数据域 //指针域 // *LinkList为Lnode类型的指针
介绍三个有用的库函数(都在 介绍三个有用的库函数(都在<stdlib.h> 中): sizeof(x)——计算变量 的长度; 计算变量x的长度 计算变量 的长度; malloc(m) —开辟 字节长度的地址空间,并返回这 开辟m字节长度的地址空间 开辟 字节长度的地址空间, 段空间的首地址; 段空间的首地址; free(p) ——释放指针 所指变量的存储空间,即彻底 释放指针p所指变量的存储空间 释放指针 所指变量的存储空间, 删除一个变量。 删除一个变量。
讨论2. 如何表示空表 空表? 空表 答: 无头结点时,当头指针的值为空时表示空表; 无头结点时,当头指针的值为空时表示空表 时表示空表; 有头结点时,当头结点的指针域为空时表示空表 时表示空表。 有头结点时,当头结点的指针域为空时表示空表。 头指针
^
头指针
头结点
^
无头பைடு நூலகம்点
有头结点
结构类型的C 结构类型的C语言表示法 教材P28对于单链表的抽象描述:
答:头指针是指向 头指针是指向 链表中第一个结点 的指针, 的指针,因此关键 是要寻找第一个结 是要寻找第一个结 地址。 点的地址。 H 31 存储地址 1 7 13 19 25 31 37 43 数据域 LI QIAN SUN WANG WU ZHAO ZHENG ZHOU 指针域 43 13 1 NULL 37 7 19 25
讨论2 单链表只能查找结点的直接后继, 讨论2: 单链表只能查找结点的直接后继, 能不能查找直接前驱?如何实现? 能不能查找直接前驱?如何实现? 答:能。只要把单链表再多开一个指针域即可(例 只要把单链表再多开一个指针域即可( 如用*next和 prior; 如用*next和*prior;) 。 prior data next 这种有两个指针的链表称为双向链表。其特点是 这种有两个指针的链表称为双向链表。 双向链表 可以双向查找表中结点。参见教材P35 39。 P35—39 可以双向查找表中结点。参见教材P35 39。
链表的实现 1. 2. 3. 单链表的插入 单链表的删除 链表的合并
实例1(和顺序表一样):一条记录有学 号和成绩两个数据项,先不考虑有序的 情况编写程序记录数据。
ch2_ltable1.c
1. 单链表的插入
在链表中插入一个元素的示意图如下: 在链表中插入一个元素的示意图如下: p a b p a x b
Pa、Pb用于搜索 和Lb, Pc指向新链表当前结点 、 用于搜索 用于搜索La和 , 指向新链表当前结点 La Pa 3 Pb 2 Pa 5 Pb 6 8 9 Pa 8 Pa 11 ^ Pb 11 ^
Lb
Lc
Pc 2
Pc 3
Pc 5 …
Pc 11 ^
算法实现: 算法实现: Void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc) { //按值排序的单链表 按值排序的单链表LA,LB,归并为LC后也按值排序 ,归并为 后也按值排序 按值排序的单链表 pa=La-->next; pb=Lb-->next; Lc=pc=La; //初始化 ; 初始化 while(pa&&pb) //将pa 、pb结点按大小依次插入 中 结点按大小依次插入C中 将 结点按大小依次插入 { if(pa->data<=pb->data) {pc->next=pa; pc=pa; pa=pa->next;} else {pc->next=pb; pc=pb; pb=pb->next} } pc->next = pa?pa:pb ; //插入剩余段 插入剩余段 free(Lb); } //MergeList_L //释放 的头结点 释放Lb的头结点 释放
p->next 插入步骤(即核心语句): 插入步骤(即核心语句): 1: Step 1:s->next=p->next; 2: Step 2:p->next=s ;
s
s->next
元素x结点应预先生成:
S=(LinkList)malloc(m); S->data=x; S->next=p->next
用链表可表示为: 用链表可表示为:
La Lb 头结点
3 2
5 6
8 8
11 9
/\
11
/\
Lc
2 8
8
3
9
5
11
6
11
/\
算法分析: 算法分析:
算法主要包括:搜索、比较、插入三个操作: 算法主要包括:搜索、比较、插入三个操作: 三个操作 搜索:需要两个指针搜索两个链表; 搜索:需要两个指针搜索两个链表; 两个指针搜索两个链表 比较:比较结点数据域中数据的大小; 比较:比较结点数据域中数据的大小; 插入:将两个结点中数据小的结点插入新链表。 插入:将两个结点中数据小的结点插入新链表。 小的结点插入新链表
注意: 的范 注意:i的范 围,循环执 行完后i的值 行完后 的值 是多少? 是多少?
单链表结点插入的演示
2. 单链表的删除
在链表中删除某元素的示意图如下: 在链表中删除某元素的示意图如下: p a × b × c
p->next
(p->next) -> next
删除步骤(即核心语句): 删除步骤(即核心语句): q = p->next; //保存b的指针,靠它才能指向 保存 的指针,靠它才能指向c p->next=q->next; //a、c两结点相连 、 两结点相连 free(q) ; //删除 结点,彻底释放 删除b结点 删除 结点, 思考: 省略free(q)语句行不行? 语句行不行 思考: 省略 语句行不行?
^
与链式存储有关的术语: 与链式存储有关的术语:
1、结点:数据元素的存储映像。由数据域和指针域两部分组成; 、结点:数据元素的存储映像。由数据域和指针域两部分组成; 2、链表: n 个结点由指针链组成一个链表。它是线性表的链式 、链表: 个结点由指针链组成一个链表。 指针链组成一个链表 存储映像,称为线性表的链式存储结构 称为线性表的链式存储结构。 存储映像 称为线性表的链式存储结构 3、单链表、双链表、多链表、循环链表: 、单链表、双链表、多链表、循环链表 • 结点只有一个指针域的链表,称为单链表或线性链表; 结点只有一个指针域的链表,称为单链表 线性链表; 单链表或 • 有两个指针域的链表,称为双链表; 有两个指针域的链表,称为双链表 双链表; • 有多个指针域的链表,称为多链表; 有多个指针域的链表,称为多链表 多链表; • 首尾相接的链表称为循环链表。 首尾相接的链表称为循环链表 循环链表。 循环链表示意图: 循环链表示意图: head a1 a2 …… an head
② 有头结点
讨论1. 在链表中设置头结点有什么好处? 头结点即在链表的首元结点之前附设的一个结点, 即在链表的首元结点之前附设的一个结点 答:头结点即在链表的首元结点之前附设的一个结点,该结
点的数据域中不存储线性表的数据元素, 点的数据域中不存储线性表的数据元素,其作用是为了对链表 进行操作时,可以对空表 非空表的情况以及对首元结点进行 空表、 的情况以及对首元结点 进行操作时,可以对空表、非空表的情况以及对首元结点进行 统一处理,编程更方便。 统一处理,编程更方便。
例: 一个线性表的逻辑结构为: 一个线性表的逻辑结构为:
ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG), ),其存 (ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG),其存 储结构用单链表表示如下,请问其头指针 头指针的 是多少? 储结构用单链表表示如下,请问其头指针的值是多少?
其它链表形式
讨论1 链表能不能首尾相连?怎样实现? 讨论1: 链表能不能首尾相连?怎样实现? 答:能。只要将表中最后一个结点的指针域指向头结 >next=head;) 点即可 (P->next=head;) 。这种形成环路的链表称 循环链表。 参见教材P35 为循环链表。 参见教材P35
特点: 特点: 1、从任一结点出发均可找到表中其他结点。 从任一结点出发均可找到表中其他结点。 2、操作仅有 一 点与单链表不同:循环条件 点与单链表不同: 单链表 ----- p = NULL 或 p ->next =NULL 循环链表----循环链表----- p= head 或 p->next = head 特别: 特别:带头结点的 空循环链表样式 H
数据结构讲义 第2章 线性表
- 链式表示和实现
信息工程学院 魏洪涛
Email:greattide@163.com
2.3 线性表的链式表示和实现
2.3 .1 链表的表示 特点: 特点: 用一组任意的存储单元存储线性表的数据元素 用一组任意的存储单元存储线性表的数据元素 任意 利用指针实现了用不相邻的存储单元存放逻辑上相邻 利用指针实现了用不相邻的存储单元存放逻辑上相邻 指针 的元素 每个数据元素a 除存储本身信息外, 每个数据元素 i,除存储本身信息外,还需存储其直 接后继的信息 结点 – 数据域:元素本身信息 数据域: – 指针域:指示直接后继的存储位置 指针域:
Status ListDelete(LinkList &L, int i, ElemType &e) {p=L->next; j=1; while(p&&j<i-1){p=p->next; ++j;} i if(!p||j>i-1)return ERROR; Q=p->next; P->next=q->next; E=q->data; Free(q); return OK;}
注意: 的范 注意:j的范 围,循环执 行完后j的值 行完后 的值 是多少? 是多少?
单链表结点的删除演示
3. 两个链表的归并(教材P31)
算法要求: 算法要求: 已知: 存储, 已知:线性表 A、B,分别由单链表 LA , LB 存储, 、 ,分别由单链表 其中数据元素按值非递减有序排列, 非递减有序排列 其中数据元素按值非递减有序排列, 要求: 归并为一个新的线性表 为一个新的线性表C 要求:将 A ,B 归并为一个新的线性表 , C 的数据 元素仍按值非递减排列 。设线性表 C 由单链表 LC 存储。 存储。 假设: ( , , , ), ),B=( , , , , ) 假设:A=(3,5,8,11), (2,6,8,9,11) 预测: 预测:合并后 C =( 2 , 3 , 5 , 6 , 8 , 8 , 9 , 11,11 ) ( ,
例 线性表 (ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG) 存储地址 头指针 H 31 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 ZHAO ZHOU QIAN WU SUN ZHENG LI WANG
何谓头指针 头结点和 头指针、 何谓头指针、头结点和首元结点?
头指针 头结点 首元结点
a1
是指向链表中第一个结点(或为头结点 头结点或 头指针是指向链表中第一个结点(或为头结点或为 首元结点)的指针。 首元结点)的指针。 单链表可由一个头指针唯一确定。 单链表可由一个头指针唯一确定。 是在链表的首元结点之前附设的一个结点; 首元结点之前附设的一个结点 头结点是在链表的首元结点之前附设的一个结点; 数据域内只放空表标志和表长等信息; 数据域内只放空表标志和表长等信息; 是指链表中存储线性表第一个数据元素a 首元结点是指链表中存储线性表第一个数据元素a1 的结点。 的结点。
ZHAO 7
∴头指针的值是31 头指针的值是
上例链表的逻辑结构示意图有以下两种形式: 上例链表的逻辑结构示意图有以下两种形式: 两种形式 H ①
ZHAO ZHOU WU QIAN SUN ZHENG LI WANG
/\
②
H ZHAO QIAN SUN LI
ZHOU
WU
ZHENG
WANG
/\
区别: 区别:① 无头结点