第3章 线性表的链式存储

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第3章 线性表的链式存储
主要知识点: 主要知识点: ● 线性表的链式存储结构。 ● 链表中有关概念的含义,如头结点、头 指针,首元结点、尾元结点的区别,以及 循环链表、双向链表的区别等。 ● 各种链表上实现线性表各种操作的方法 即有关算法的设计。 ● 建立利用数据结构知识进行程序设计的 思考方式。
教学重点与难点 重点:顺序表单链表结构的各种基本算法,以 及相关的时间性能分析。 难点:设计链表结构算法解决线性表相关实际 问题。 思考问题: 思考问题: 1、线性表链式结构特点 2、如何利用线性表链式结构的知识解决实际问 题,确定线性表链式结构的应用题目。
【知识拓展】:指针变量和结点变量的关系
(1)、生成结点变量的标准函数 p=( LNode *)malloc(sizeof(LNode)); //函数malloc分配一个类型为ListNode的结点变量的空间, 并将其首地址放入指针变量p中。 (2)、释放结点变量空间的标准函数 free(p); //释放p所指的结点变量空间。 (3)结点分量的访问 利用结点变量的名字*p访问结点分量 方法一:(*p).data和(*p).next 方法二:p-﹥data和p-﹥next (4)、指针变量p和结点变量*p的关系 指针变量p的值——结点地址 结点变量*p的值——结点内容 (*p).data的值——p指针所指结点的data域的值 (*p).next的值——*p后继结点的地址 *((*p).next)——*p后继结点
3.1 线性表的链式存储结构
3.1.1 为什么要使用链式存储结构
【案例】:饮食中心快餐配送餐管理 。 案例】
图 3.1 快餐配送信息
3.1 线性表的链式存储结构
需求分析: 需求分析: 1、不需要事先准备一张足够大的纸; 、不需要事先准备一张足够大的纸; 2、每张小纸条写完以后,把这张纸条排列到正确 、每张小纸条写完以后, 位置时,不会影响到其他的纸条; 位置时,不会影响到其他的纸条; 3、订餐顾客用完餐后,把记录该顾客信息的纸条 、订餐顾客用完餐后, 抽出来销毁(或存档)。 抽出来销毁(或存档) 4、数据元素之间的逻辑关系为线性关系。 、数据元素之间的逻辑关系为线性关系。 问题思考: 、预定顺序如采用顺序表物理存储结构存在的问题。 问题思考:1、预定顺序如采用顺序表物理存储结构存在的问题。 2、考虑采用链式物理存储结构的解决。 、考虑采用链式物理存储结构的解决。
头结点及作用: 头结点是在链表的开始结点之前附加一个结点。它具有两个优点: (1).由于开始结点的位置被存放在头结点的指针域中,所以 在链表的第一个位置上的操作就和在表的其它位置上操作一 致,无须进行特殊处理; (2).无论链表是否为空,其头指针都是指向头结点的非空指 针(空表中头结点的指针域空),因此空表和非空表的处理 也就统一了。 注意: 注意: 头结点数据域的阴影表示该部分不存储信息。在有的应用中 可用于存放表长等附加信息
3.2 基于单链表的算法实现
【例3-3】:以“饮食中心快餐配送餐管理”任务为例, 采用带头结点的动态链表设计数据结构。 单链表类型定义: (1).定义元素数据类型 typedef struct { char number[7]; /*序号*/ char name[10]; /*姓名*/ char time[10];/*时间*/ int amount;/*人数*/ } ElemType; (2). 定义链表及结点类型 typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
3.2 基于单链表的算法实现
3.2.1 单链表的基本算法实现
1.构造一个空表 /*构造一个空表 构造一个空表* int Init_LinkList(LinkList *Head_pointer) /*构造一个空表*/ { LinkList p; /*分配一个结点 分配一个结点* p=(LinkList)malloc(sizeof(LNode)); /*分配一个结点*/ if (p==NULL) /*分配失败 分配失败* return OverFlow; /*分配失败*/ /*头指针指向新结点 头指针指向新结点* *Head_pointer=p; /*头指针指向新结点*/ /*构造成功 构造成功, return OK; /*构造成功,返回 */ }
任务2:静态链表存储结构举例并采用C语言定义
3.1.4 动态链表的实现
使用链表的原因: 使用链表的原因: 第一, 第一,如果系统不能提供足 够大的地址连续的内存空 间时,可以考虑使用链表; 间时,可以考虑使用链表; 第二, 第二,需要对线性表频繁地 进行插入和删除操作时, 进行插入和删除操作时, 也考虑使用链表。 也考虑使用链表。 动态链表结点定义一般形式: typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
3.1.2 单链表的数据定义
结点结构:
数据域
指针域
数据域:存放结点数据信息值,例如订餐顾客数据信息。 指针域:存放结点的直接后继的地址(位置)。 注意: 注意: (1)、链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。 (2)、每个结点只有一个链域的链表称为单链表(Single Linked List)。
例3-1:饮食中心快餐配送餐管理静态链表存储结构设计 (1)存储结构分析
(2)存储结构C语言定义如下: 定义顾客信息数据类型: typedef struct { char name[10]; /*姓名*/ char time[10]; /*时间*/ int amount; /*份数*/ char adress[17]; /*地址*/ } ElemType; 定义结点类型: typedef struct node { ElemType data; /*数据域 */ Int next; /*指针域 */ } SLNode; 定义静态单链表: SLNode letter[100]
3.1.4 动态链表的实现
例3-2:饮食中心快餐配送餐管理动态链表存储结构设计 1.存储结构分析: 而在C语言程序设计中,可以用malloc函数申请动态变量(存储空间),用 free释放变量(存储空间)。动态链表中的结点是以变量形式申请或者释放 的。 2.订餐顾客信息的动态链类型:
(1).定义元素数据类型 ) 定义元素数据类型 typedef struct { char number[7]; /*序号 序号*/ 序号 char name[10]; /*姓名 姓名*/ 姓名 char time[10];/*时间 时间*/ 时间 int amount;/*人数 人数*/ 人数 } ElemType;
子函数参数说明: 子函数参数说明:
typedef struct node { ElemType data; /*数据域 */ 数据域 struct node *next; /*指针域 */ 指针域 } LNode,*LinkList ,
int InsertL_i(LinkList Head, ElemType x,int i) /*在第 个结点后面插入 在第i个结点后面插入 在第 个结点后面插入*/ { LNode *p,*q;int k=0; p=( LinkList)malloc(sizeof(Node)); /*分配一个结点 分配一个结点*/ 分配一个结点 if (p==NULL) return OverFlow; /*分配失败 分配失败*/ 分配失败 /*数据域赋值 数据域赋值*/ 数据域赋值 strcpy(p->data.number,x.number);/*输入序号 输入序号*/ 输入序号 strcpy(p->data.name,x.name);/*输入姓名 输入姓名*/ 输入姓名 strcpy(p->data.time,x.time);/*输入时间 输入时间*/ 输入时间 p->data.amount=x.amount;/*输入人数 输入人数*/ 输入人数 q=Head; while(q!=NULL && k!=i-1) /*q指向第一个元素 指向第一个元素*/ 指向第一个元素 { q=q->next;k++; /*q取后继元素的指针 取后继元素的指针*/ 取后继元素的指针 } if (q==NULL) printf(“序号错 序号错/n”); 序号错 else { p->next=q->next; /*设置新结点的指针指向第 个结点的后继结点 设置新结点的指针指向第i个结点的后继结点 设置新结点的指针指向第 个结点的后继结点*/ q->next=p; /*设置第 个结点的指针域指向新结点 设置第i个结点的指针域指向新结点 设置第 个结点பைடு நூலகம்指针域指向新结点*/ return OK; /*插入成功,返回 */ 插入成功, 插入成功 } return Error; /*插入未成功 插入未成功*/ 插入未成功 }
3.C语言描述说明 (1).LinkList和LNode * 是不同名字的同一个指针类型(命名的不同是为了概念 上更明确)。 (2).LinkList类型的指针变量head表示它是单链表的头指针。 (3).LNode *类型的指针变量p表示它是指向某一结点的指针。 为了便于描述,下面给出有关链表的术语。在一个链表中称表头结点指针为 头指针,如图 3.5 Head指针变量。由于从头指针出发可以搜索到链表中各结点, 头指针 因而常用头指针作为链表的名称,如图 3.5快餐配送信息链表为Head。 4.定义链表变量两种定义形式: (1)LinkList Head; (2)LNode *Head;
课程任务:线性表链式结构案例理解,完成课程任务设计。 课程任务:线性表链式结构案例理解,完成课程任务设计。 1、考核方式:课程报告和程序设计 、考核方式: 2、作业题目:依据选定的线性表结构实用案例题目,设计完 、作业题目:依据选定的线性表结构实用案例题目, 成课程任务。例如: 饮食中心订餐管理系统 系统” 成课程任务。例如:课程任务实例 “饮食中心订餐管理系统”。 3、作业要求:分析案例实现方法,结合案例设计自己的作业 、作业要求:分析案例实现方法, 任务。 任务。
问题思考: 问题思考:总结链式存储结构的特点
单链表定义的一般形式: 由分别表示a1,a2,…,an, 的n 个结点依次相链构成的链表,称为线性表的链 式存储表示,由于此类链表的每个结点中只包含一个指针域,故称为单链 表或线性链表。 任务1: 任务 :举例说明为什么要使用链式存储结构。
3.1.3静态链的实现 静态链的实现 静态链表特点: ● 用数组来存储元素的值和地址。 ● 程序运算过程中,数组元素的个数固定不变。
3.1.2
单链表的数据定义
链表的存储特点(参见图3.2): 1、 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以 是连续的,也可以是不连续的),例如三个订餐顾客的订餐数据信息的 存储空间是可以定义在任意的存储区域。 2、链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点 间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点 的地址(或位置)信息(如图3.2B),三个订餐顾客的订餐数据的逻辑 次序与物理存储次序不相同。
typedef struct node data; { ElemType data; /*数据域 /*数据域 */ struct node *next; *next; /*指针域 /*指针域 */ LNode, LinkList; } LNode,*LinkList;
(2). 定义链表及结点类型 typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
相关文档
最新文档