第三章 线性表的链式存储结构教案

合集下载

线性表的链式存储

线性表的链式存储

序号 0 1 2
数据域 邓玉莹配送信息 魏秀婷配送信息 刘佳佳配送信息
指针域 1 -1 0



任务2:静态链表存储结构举例并采用C语言定义
3.1.4 动态链表的实现
Head
刘佳佳配送信息 ^
Head
Head
刘佳佳配送信息
邓玉莹送信息
魏秀婷配送信息
动态链表结点定义一般形式: typedef struct node { ElemType data; /*数据域 */ struct node *next; /*指针域 */ } LNode,*LinkList;
4.定义链表变量两种定义形式: (1)LinkList Head; (2)LNode *Head;
【知识拓展】: 指针变量和结点变量的关系
(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后继结点
问题思考:总结链式存储结构的特点
单链表定义的一般形式: 由分别表示a1,a2,…,an, 的n 个结点依次相链构成的链表,称为线性表的 链式存储表示,由于此类链表的每个结点中只包含一个指针域,故称为 单链表或线性链表。

数据结构线性表的链式存储结构

数据结构线性表的链式存储结构

南昌航空大学实验报告课程名称:数据结构实验名称:实验二:线性表的链式存储结构班级: 080611 学生姓名:赖凌学号: 08061101指导教师评定:签名:题目:设计并实现以下算法:给出用单链表存储多项式的结构,利用后接法生成多项式的单链表结构,实现两个多项式相加的运算,并就地逆置相加后的多项式链式。

一、需求分析⒈实现两张线性表的链式存储,合并及删除值相同元素的操作。

⒉在演示过程序中,用户敲击键盘,即可观看演示结果。

⒊程序执行的命令包括:(1)构造线性链表A (2)构造线性链表B (3)求两张表的并(4)删除C中值相同的元素二、概要设计⒈为实现上述算法,需要线性表的抽象数据类型:ADT LinkList List {数据对象:D={a i:|a i∈ElemSet,i=1…n,n≥0}数据关系:R1={<a i-1,a i>|a i-1,a i∈D,i=2,…n≥0}基本操作:Status InitList( LinkList &L)//操作结果:构造一个空的线性链表L。

Status MakeNode ( Link &p, ElemType e );// 分配由p指向的值为e 的结点,并返回OK;若分配失败,则返回ERRORStatus Append (LinkList &L,Link s);//将指针s所指(彼此以指针相链接)的一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新的尾结点Status ListEmpty(LinkList L);//若线性链表L为空表,则返回TRUE,否则返回ERROR。

Int ListLength(LinkList L);//返回线性链表中L最后一个结点的位置。

ElemType GetCurElem(Link p);//已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值Position GetHead (LinkList L);//返回线性链表L中头结点的位置Position GetLast( LInkList L);//返回线性链表L中最后一个结点的位置}ADT LinkList2. 本程序有三个模块:⑴主程序模块void main(){初始化;{接受命令;显示结果;}}⑵线性链表单元模块:实现线性链表抽象数据类型;⑶结点结构单元模块:定义线性链表中的结点结构。

第3章线性表的链式存储

第3章线性表的链式存储
L
(a) 空循环链表
L
a1
a2
...
an
(b) 非空循环链表
3.1.3 双向链表
在单链表结点中只有一个指向其后继结点的next 指针域,而找其前驱则只能从该链表的头指针开始,顺 着各结点的next指针域进行查找,也就是说找后继的时 间复杂度是O(1),找前驱的时间复杂度是O(n)。如果也 希望找前驱像后继那样快,则只能付出空间的代价:每 个结点再加一个指向前驱的指针域prior,结点的结构修 改为下图,这样链表中有两个方向不同的链,用这种结 点组成的链表称为双向链表。
1.带头结点的单链表 2.不带头结点的单链表
3.3.3 单链表插入操作的实现
单链表的插入操作是指在表的第i个位置结点处插入 一个值为data的新结点。插入操作需要从单链表的第一个结 点开始遍历,直到找到第i个位置的结点。插入操作分为在 结点之前插入的前插操作和在结点之后插入的后插操作。
1.前插操作 2.后插操作
2.整数型单链表算法
3.不带头结点的单链表算法
3.2.2 尾插法单链表的创建实现
用头插法实现单链表的创建,比较简单,但读入的 数据元素的顺序与生成的链表中元素的顺序是相反的。若希 望两者次序一致,则用尾插法创建单链表。为了快速找到新 结点插入到链表的尾部位置,所以需加入一个尾指针r用来 始终指向链表中的尾结点。初始状态:头指针L和尾指针r均 为空,把各数据元素按顺序依次读入,申请结点,将新结点 插入到r所指结点的后面,然后r指向新结点,直到读入结束 标志为止。
3.2.2 尾插法单链表的创建实现
L
插入P前的尾指针 插入P后的尾指针
r
3
4
P1
x^
2
3.3 单链表运算的实现

武汉软件工程职业学院《数据结构讲义》第04讲-线性表的链式存储结构

武汉软件工程职业学院《数据结构讲义》第04讲-线性表的链式存储结构

1.掌握线性链表、单链表、静态链表的概念。

2.掌握线性链表的表示及实现方法。

➢ 教学重点:线性链表之单链表的表示及实现方法。

➢ 教学难点: 线性链表的概念。

➢ 授课内容2.3 线性表的链式存储结构由于顺序表的存贮特点是用物理上的相邻实现了逻辑上的相邻,它要求用连续的存储单元顺序存储线性表中各元素,因此,对顺序表插入、删除时需要通过移动数据元素来实现,影响了运行效率。

本节介绍线性表链式存储结构,它不需要用地址连续的存储单元来实现,因为它不要求逻辑上相邻的两个数据元素物理上也相邻,它是通过“链”建立起数据元素之间的逻辑关系来,因此对线性表的插入、删除不需要移动数据元素。

2.3.1单链表链表是通过一组任意的存储单元来存储线性表中的数据元素的,那么怎样表示出数据元素之间的线性关系呢?为建立起数据元素之间的线性关系,对每个数据元素a i ,除了存放数据元素的自身的信息 a i 之外,还需要和a i 一起存放其后继 a i+1 所在的存贮单元的地址,这两部分信息组成一个“结点”,结点的结构如图2.6 所示,每个元素都如此。

存放数据元素信息的称为数据域,存放其后继地址的称为指针域。

因此n 个元素的线性表通过每个结点的指针域拉成了一个“链子”,称之为链表。

因为每个结点中只有一个指向后继的指针,所以称其为单链表。

链表是由一个个结点构成的,结点定义如下: typedef struct node{ datatype data;struct node *next;} LNode ,*LinkList ; 定义头指针变量: LinkList H ;如图2.7是线性表 (a 1,a 2,a 3,a 4,a 5,a 6,a 7,a 8) 对应的链式存储结构示意图。

第四讲 线性表的链式存储结构图2.6 单链表结点结构 data next当然必须将第一个结点的地址160 放到一个指针变量如 H 中,最后一个结点没有后继, 其指针域必需置空,表明此表到此结束,这样就可以从第一个结点的地址开始“顺藤摸瓜”,找到每个结点。

线性表的链式存储结构

线性表的链式存储结构

19
1. 初始化链表 :即只有一个头结点,并且头结点的 初始化链表CL:即只有一个头结点, next域指向它自身。 域指向它自身。 域指向它自身 int InitList(LinkList *CL) { CL->head=(*LNode)malloc(sizeof(LNode)); if (CL->head) {CL->head->next=CL->head; return OK;} //让next域指向它自身 让 域指向它自身 else return ERROR ; }
16
10. 在链表 中第 个数据元素之前插入数据元素 在链表L中第 个数据元素之前插入数据元素e 中第i个数据元素之前插入数据元素 int ListInsert(LinkList *L,int i,EntryType e) { LNode *p,*s; int j; if (i<1||i>ListLength(L)+1) return ERROR; s=(LNode*)malloc(sizeof(LNode));//s为存放 的结点 为存放e的结点 为存放 if (s==NULL) return ERROR; s->data=e; for (p=L->head,j=0;p&&j<i-1;p=p->next;j++); //寻找第 个结点 寻找第i-1个结点 寻找第 s->next=p->next; p->next=s; //将s结点插入 将 结点插入 return OK; }//P25图2-9。 图 。
8
2. 销毁链表 :删除链表中包括头结点在内所有结点。 销毁链表L:删除链表中包括头结点在内所有结点。 void DestoryList(LinkList *L) { LNode *p; while (L->head){ //依次删除链表中的所有结点 依次删除链表中的所有结点 依次

2-4线性数据结构链式存储结构

2-4线性数据结构链式存储结构

ZHAO
QIAN
SUN
LI
NULL
To link ‘ZHAO’ and ‘QIAN’:
Head pointer ptr = 0110
list_ptr N1, N2 ;
N1 = (list_ptr)malloc(sizeof(struct list_node));
Definition:
节点的位置NN12-在=>d(la每istat_次=pt‘Zr运)HmAa行Ollo’ 时;c(sizeof(struct list_node));
} return status; }
也可用复合条件将循环改写 为:
while(p && p->data != elem ){
i++; p=p->next; }
数据结构@UESTC 电子科技大学 ·计算机科学 ·数据结构与算法 ·
思考: 能不能用递归程序实现?
数据结构@UESTC 电子科技大学 ·计算机科学 ·数据结构与算法 ·
循环条件分析:
p = (*L)->next ; i=1; while (p && i<pos ) { i++;p=p->next;}
条件1防止pos>表长,条件2控制取第pos个,并防止了pos<1
两个条件有6种组合:
1.p== NULL && i<pos 空表且pos>1 或pos>表长+1,range_error
}
return status;
}
数据结构@UESTC 电子科技大学 ·计算机科学 ·数据结构与算法 ·
③ 单链表上的删除操作 删除单链表第i个元素: List_Remove(ListPtr L, int pos)

数据结构-线性表链式存储结构

数据结构-线性表链式存储结构

04 线性表链式存储结构的实 现
C语言实现
创建链表
通过动态内存分配,创建链表节 点并逐个连接起来,形成链表。
插入节点
在链表指定位置插入节点,需要 更新插入位置节点的指针域,使 其指向新插入的节点。
删除节点
删除链表中的指定节点,需要更新被 删除节点前一个节点的指针域,使其 指向被删除节点的下一个节点。
01
遍历链表
从头节点开始,依次访问链表中的每 个节点,输出节点的数据值。
05
03
插入节点
在链表指定位置插入节点,需要更新 插入位置节点的引用,使其指向新插 入的节点。
04
删除节点
删除链表中的指定节点,需要更新被 删除节点前一个节点的引用,使其指 向被删除节点的下一个节点。
Python语言实现
在Python中,可以使
THANKS FOR WATCHING
感谢您的观看
适用场景
链式存储结构适用于需要频繁进行插入、删除等操作的数据结构,如动态数组、队列、链表等。
展望
01 02 03
未来发展方向
随着大数据和云计算的普及,数据结构的应用场景越来越 广泛,链式存储结构作为其中的一种重要形式,未来将有 更多的应用场景和优化空间。例如,针对大数据场景下的 链式存储结构优化、新型的链式数据结构等都是值得研究 的方向。
06 总结与展望
总结
定义与特点
链式存储结构是线性表的另一种存储方式,它通过在数据元素之间建立指针链接,实现了数据元素的逻辑顺序与物理 顺序的分离。相比于顺序存储结构,链式存储结构具有更好的动态性,能够方便地插入、删除等操作。
基本操作
链式存储结构支持的主要操作包括插入、删除、查找等,这些操作的时间复杂度通常为O(1)、O(n)、O(n),其中n为链表 长度。

第3章 线性表及其存储结构

第3章 线性表及其存储结构

链式存储结构,既可用来表示线性结构, 也可用来表示非线性结构。线性表的链式存 储结构,称为线性链表。 对线性链表而言,它不要求逻辑上相邻的 元素在物理位置上也相邻。其存储单元既可 以是连续的,也可以是不连续的,甚至可以 零散分布在内存中的任何位置上。 通常,为了适应线性链表的存储,计算机 的存储空间被划分成一个一个的小块,每一 小块占若干字节,这些小块就是存储结点。 存储结点的结构,如图 3-2 所示。
在稍微复杂的线性表中,一个数据元素还 可以由若干个数据项组成。例如,某班的学 生情况登记表是一个复杂的线性表,表中每 一个学生的情况就组成了线性表中的每一个 元素,每一个数据元素包括学号、姓名、性 别、入学成绩4个数据项。
3.2线性表的顺序存储及其运算
3.2.1 线性表的顺序存储 线性表的顺序存储结构称为顺序表。
第3章 线性表及其存储结构
3.1线性表的基本 概念 3.2线性表的顺序 存储及运算 3.3线性表的链式 存储及运算
3.1 线性表的基本概念
线性表是由 n (n≥0)个数据元素 a1 ,a2 ,…,an 组成的一个有限序列。表中的每一个数据元 素,除了第一个外,有且只有一个前件;除 了最后一个外,有且只有一个后件。即线性 表或是一个空表或可以表示为:
(a1 ,a2 ,…,ai ,…,an)其中 ai(i=1,2,…,n) 是属于数据对象的元素,通常也称其为线性 表中的一个结点。
数据元素在线性表中的位置,只取决于它们 自己的序号 。 非空线性表的结构特征为: ① 有且只有一个根结点a1 ,它无前件;
② 有且只有一个终端结点an ,它无后件;
③ 除根结点与终端结点外,其他所有结点 有且只有一个前件,也有且只有一个后件。线 性表中结点的个数n称为线性表的长度。当 n=0时,称为空表。

第3章数据结构基本类型3.3操作受限的线性表——队列-高中教学同步《信息技术-数据与数据结构》(教案

第3章数据结构基本类型3.3操作受限的线性表——队列-高中教学同步《信息技术-数据与数据结构》(教案
作业布置
编程实践:请实现一个循环队列,包含入队(enqueue)、出队(dequeue)、判断队列是否为空(is_empty)等基本操作。你可以使用Python语言进行编程,并编写相应的测试用例来验证你的实现。
理论思考:
思考并解释为什么队列的“先进先出”特性在现实生活中有广泛的应用。
假设你是一家大型超市的经理,你需要设计一个顾客结账排队系统。请说明你会如何利用队列的原理来设计一个既高效又公平的排队系统。
队列的应用:
结合日常生活中的排队场景,解释队列原理的实际应用,如银行取号系统、医院挂号系统等。
强调队列在处理具有“先来先服务”特性问题时的有效性,以及如何通过队列来优化服务流程。
教学难点
循环队列的实现与理解:
理解循环队列如何通过循环使用数组空间来避免“假溢出”现象。
掌握如何根据队列的头部和尾部指针判断队列的空和满状态。
完成后与同学交流并分享自己的解题思路和经验。
通过编程练习巩固所学知识,提高学生的编程能力和解决实际问题的能力。
鼓励学生互相交流和讨论,培养学生的团队协作能力和沟通能力。
课堂小结
作业布置
课堂小结
本节课我们深入学习了数据结构中的队列(Queue)这一重要概念。首先,通过日常生活中排队的例子,我们直观地理解了队列的基本特点——先进先出(FIFO),即新加入的元素总是排在队尾,而需要处理的元素总是从队头开始。
准备课后作业:设计一些与队列相关的课后作业,如编写顺序队列和链式队列的实现代码、分析队列在实际问题中的应用等,以巩固学生的学习效果。
教学媒体
教材或讲义:
提供了队列的基本概念、特征、实现方式以及应用实例的文字描述。
包含了队列的抽象数据类型定义、队列的存储结构(顺序队列、循环队列、链队列)等核心知识点的详细解释。

第3章数据结构基本类型3.1线性表-高中教学同步《信息技术-数据与数据结构》(教案)

第3章数据结构基本类型3.1线性表-高中教学同步《信息技术-数据与数据结构》(教案)
学生预习:
布置预习任务,要求学生提前阅读线性表的基础知识和概念。
发放预习材料,如PPT、视频教程或预习习题。
课堂讨论引导:
准备引导性问题,鼓励学生积极参与课堂讨论。
设计小组活动,促进学生之间的合作与交流。
课后反馈:
设计课后习题和作业,以检验学生的学习效果。
准备课后答疑和辅导,为学生提供必要的帮助和支持。
确保教学环境中网络连接稳定,以便在需要时展示在线资源或示例。
教学媒体
教学媒体
PPT演示文稿:
线性表的基本概念、定义、特点和示例的幻灯片。
顺序存储和链式存储的对比图示。
线性表基本操作(如初始化、查找、插入、删除)的动画或图解。
代码编辑器/IDE:
演示顺序表和链表的实现代码(如Python)。
允许学生直接看到、理解和操作代码。
情感、态度与价值观:
激发学生的学习兴趣和创造力,培养学生的探索精神和创新精神。
引导学生认识到数据结构在解决实际问题中的重要性,形成合理的计算机思维观念。
学习重难点
教学重点
线性表的基本概念:理解线性表是什么,它如何表示具有相同பைடு நூலகம்型数据元素的有限序列,并理解其特点,包括唯一的首尾元素以及除首尾外每个元素有且仅有一个前驱和后继。
准备用于课堂讨论的实例和问题,如通信录的设计和实现。
准备教学用计算机和相关编程环境(如Python环境),以便现场演示代码和执行结果。
教学流程设计:
设计教学流程,从线性表的基础概念引入,逐步深入到线性表的存储方式和操作。
设计课堂互动环节,如提问、小组讨论等,鼓励学生积极参与和表达。
安排编程实践环节,让学生亲自编写线性表相关操作的代码,加深理解。
线性表的应用场景:通过通信录的实例,了解线性表在实际问题中的应用,并理解如何根据需求选择合适的数据结构和存储方式。

线性表的链式存储

线性表的链式存储

(1)
head
(1)
^
(1)head=head->next;
q (a)删除单链表的最前面的结点 (1)
head
(1) pre q (1)pre->next=q->next;
^
(b)删除q指向的结点,pre为q的前驱结点 图3.5 单链表的删除过程图示
node *dele(node *head,datatype x) { node *pre=NULL,*p; if(!head) {printf(“单链表是空的!”); return head;} p=head; while(p&&p->info!=x) {pre=p; p=p->next;} if(p) { if(!pre) head=head->next; else pre->next=p->next; free(p); } return head; } 算法3.5 在单链表中删除一个值为x的结点
node *find(node*head,int i) { int j=0; node *p=head; if(i<1) return NULL; else if (i==0) return p; while(p&&i!=j) { p=p->next; j++; } return p; } 算法3.3 在带头结点的单链表中查找第i个结点
(1)
head
(1) q
^
(1)pre->next=q->next;
(a)删除带头结点的单链表的最前面的结点 (1) head
(1) pre q (1)pre->next=q->next;

《数据结构》多媒体课件 线性表的链式表示和实现

《数据结构》多媒体课件 线性表的链式表示和实现

总结
单链表的存储特点:逻辑上相邻的元素,物理 上未必相邻
单链表的操作特点:
只适合顺序访问
插入、删除元素丌必移动元素,只需修改 指针
线性表的两种实现方式的比较
实现方式 存储特点 存储密度 适合的运算 访问方式
顺序表 链 表
连续 不一定连续
100% 低于100%
查找 插入、删除
直接、顺序
1)生成结点: s=(LinkList)malloc(sizeof(LNode)); scanf(&s->data); s->next=NULL; 2)插入表尾: p->next=s; p=s;
建立单链表 头插法:将结点插入表首,即头结点之后。 L ^ a ^
c
p p
b
p
1)生成结点: p=(LinkList)malloc(sizeof(LNode)); scanf(&s->data); 2)插入表首: p->next=L->next; L->next=p;

s
ai-1 e
ai

an ^
①无前驱结点 ②有前驱结点
1)查找插入位置: 表首或空表(无前驱结点): 其他位置(有前驱结点):若题中明确在第i个元素前插 入,则需通过计数,找到第i-1个结点;若未明确插入位置, 则需进行元素值的比较,找到插入位置前一结点。
插入操作
在丌带头结点的单链表中插入 p L s 插入位置 插入位置的合法范围
删除操作
status ListDelete_L(LinkList &L, int i, ElemType &e){ //在带头结点的单链表L中,删除第i个元素,并用e返回其值 p=L;j=0; while(p->next&&j<i-1) {p=p->next; j++;} //顺指针找第i-1个结点 if(!(p->next)||j>i-1) return ERROR; //i小于1或i大 q=p->next; //q指向第i个结点 p->next=q->next; e=q->data; free(q); //释放所删结点的空间 return OK; } //ListDelete_L

线性表的链式存储结构

线性表的链式存储结构

石家庄经济学院实验报告学院: 信息工程学院专业: 计算机信息工程学院计算机实验中心制一 实验内容1.进一步熟悉C 语言的上机环境,掌握C 语言的基本结构。

2.会定义线性表的链式存储结构。

3.熟悉对单链表的一些基本操作(建表、插入、删除等)和具体的函数定义。

二 实验目的掌握链式存储结构的特点,了解、掌握并实现单链表的常用的基本算法。

三 需求设计线性表抽象数据类型的描述及实现ADT List{数据对象: {|,,,,,0}i i D a a ElemSet i 12n n =∈=≥数据关系: {,|,,,,}i 1i i 1i R a a a a D i 2n --=<>∈=基本操作:构造一个空的线性表L InitList();销毁线性表L DestroyList();将L 重置为空表 ClearList();判断L 是否为空 ListEmpty();求表长 ListLength();查找元素 LocateElem();求前驱 PriorElem();求后继 NextElem();插入元素ListInsert();删除元素ListDelete();元素调用visit()函数ListTraverse(L,visit())}ADT List;程序具体实现要求:1.创建一个线性表2.能输出所有数据元素3.能求线性表长度4.能插入删除元素5.能查找元素6.能求元素的前驱和后继7.用户操作界面如下:*********************************** 1. 构造线性表* 2. 插入元素* 3. 删除元素* 4. 查找元素* 5. 显示表长* 6. 求后继* 7. 求前驱* 8. 输出所有元素* 0. 结束程序运行*********************************** 请输入您的选择(0,1,...,8):四详细设计步骤4:上机编程与调试主程序如下:#include "stdafx.h"#include "stdio.h"#include "LinkList0515.h"#include "user.h"#include "Fun.h"int main(int argc, char* argv[]){CLinkList0515 L;LinkList l;int flag,flag1=0,loc,e,next_e,pre_e;printf("\n**************************************"); printf("\n* 1. 构造单链表");printf("\n* 2. 插入元素");printf("\n* 3. 删除元素");printf("\n* 4. 查找元素");printf("\n* 5. 显示表长");printf("\n* 6. 求后继");printf("\n* 7. 求前驱");printf("\n* 8. 输出所有元素");printf("\n* 0. 结束程序运行");printf("\n**************************************");while(1){printf("\n请输入您的选择(0,1,...,8): ");scanf("%d",&flag);switch(flag){case 0:++flag1;break;case 1:if(OK==L.InitList_L(l))printf("\n成功完成单链表初始化操作!\n");elseprintf("\n操作失败,内存溢出!\n");break;case 2:printf("\n 请输入插入元素的位序,值(空格隔开): ");scanf("%d %d",&loc,&e);if(ERROR==L.ListInsert_L(l,loc,e))printf("\n操作失败,可能是插入位序不合理!\n");elseprintf("\n成功完成操作!\n");L.ListTraverse_L(l,DisplayData);break;case 3:printf("\n 请输入被删除元素的位序: ");scanf("%d",&loc);if(ERROR==L.ListDelete_L(l,loc,e))printf("\n操作失败,可能是位序不合理!\n");else{ printf("\n元素 %d 成功被删除!\n",e);L.ListTraverse_L(l,DisplayData);}break;case 4:printf("\n 请输入待查找的元素的值: ");scanf("%d",&e);loc=L.LocateElem_L(l,e,compare);if(!loc)printf("\n表中不存在元素 %d !\n",e);elseprintf("\n找到了,元素 %d 在表中的位置是: %d \n",e,loc);break;case 5:printf("\n表长为: %d \n",L.ListLength_L(l));break;case 6:printf("\n 请输入元素的值: ");scanf("%d",&e);if(ERROR==L.NextElem_L(l,e,next_e))printf("\n表中元素 %d 没有后继!\n",e);elseprintf("\n表中元素%d 的后继是: %d\n",e,next_e);break;case 7:printf("\n 请输入元素的值: ");scanf("%d",&e);if(ERROR==L.PriorElem_L(l,e,pre_e))printf("\n表中元素 %d 没有前驱!\n",e);elseprintf("\n表中元素%d 的前驱是: %d \n",e,pre_e);break;case 8:L.ListTraverse_L(l,DisplayData);break;default:break;} //switchif(flag1==1) break;}//whileprintf("\n结束!\n\n\n");return 0;}运行结果如下:图3.1五实验总结1. 基本掌握线性表链式存储结构的特点;2. 基本掌握单链表的常用的基本操作算法;3. 通过线性表的抽象数据类型的学习,进一步掌握抽象数据类型的定义方法;4. 对于同一个线性表,用顺序结构和链式存储结构实现,算法也不同;从而可知,逻辑结构依赖于物理结构;。

线性表的链式存储结构设计

线性表的链式存储结构设计

实验一:设线性表L1和L2分别代表集合A和B,试设计算法求A 和B的并集C,并用线性表L3代表集合C。

实验二:设计一个一元多项式计算器,要求能够:①输入并建立多项式;②输出多项式;③执行两个多项式相加;④执行两个多项式相减。

1.实验目的:掌握线性表的链式存储结构设计与基本操作的实现。

2.实验内容与要求:⑴定义线性表的链式存储表示;⑵基于所设计的存储结构实现线性表的基本操作;⑶编写一个主程序对所实现的线性表进行测试;3.数据结构设计实验一:逻辑结构:线性结构存储结构:链式存储结构实验二:逻辑结构:线性结构存储结构:链式存储结构4.算法设计实验一#include<stdio.h>#include<stdlib.h>typedef int datatype;typedef struct node{datatype data; //结点值struct node *next; //存储下一个结点的地址}LinkList;LinkList *CREATLISTF(LinkList *L,int n) {int num,i;LinkList *head,*s,*r;head=L;r=head;head->next=NULL;printf("请输入集合中的元素(由小到大):\n");for(i=0;i<n;i++){scanf("%d",&num);s=(LinkList*)malloc(sizeof(LinkList));s->data=num;r->next=s; //链接到表中r=s; //r指向新的尾结点}r->next=NULL;return head;}LinkList *merge(LinkList *L1,LinkList *L2){LinkList *L3,*pa,*pb1,*pb2,*pc;L3=(LinkList*)malloc(sizeof(LinkL ist));//申请结点L3->next=NULL; //初始化链表L3pa=L1->next; //pa是链表L1的工作指针,指向第一个结点pb1=pb2=L2->next; //pb1是链表L2的工作指针,指向第一个结点pc=L3; //pc是链表L3的工作指针,指向头结点while(pa && pb1) //L1和L2均非空if(pa->data<pb1->data){//L1中元素插入L3pc->next=pa; pc=pa; pa=pa->next;}else if(pa->data>pb1->data){//L2中元素插入L3pc->next=pb1; pc=pb1; pb1=pb1->next;}else{pc->next=pa;pc=pa;pa=pa->next; pb1=pb2=pb1->next;}if(pa) pc->next=pa; //若pa未到尾,将pc指向paelse pc->next=pb1; //若pb1未到尾,将pc指向pb1return(L3);}void display(LinkList *L){LinkList *head;head=L->next;do{printf("%d\t",head->data);head=head->next;}while(head!=NULL);}void main(){int an,bn;LinkList *L1,*L2,*L3;L1=(LinkList*)malloc(sizeof(LinkL ist));L2=(LinkList*)malloc(sizeof(LinkL ist));printf("\n请输入集合A中元素的个数:\n");scanf("%d",&an);*L1=*CREATLISTF(L1,an);printf("集合A的元素为:\n");display(L1);printf("\n请输入集合B中元素的个数:\n");scanf("%d",&bn);*L2=*CREATLISTF(L2,bn);printf("集合B的元素为:\n");display(L2);L3=merge(L1,L2);printf("交集为:\n");display(L3);}实验二typedef struct node{ int coef;int exp;struct node *next;}polynode;polynode *Creat1polynode();polynode *Creat2polynode();polynode *subpolynode(polynode *ha,polynode *hb);polynode *addpolynode(polynode *ha,polynode *hb);#include<stdlib.h>#include<stdio.h>int main(){ polynode *ha,*hb,*hc,*hd,*p;ha=Creat1polynode();p=ha->next;printf("输出多项式A:");if(p->exp==0)printf("%d",p->coef);elseprintf("%dx^%d",p->coef,p->exp); p=p->next;while(p!=NULL){ if(p->coef>0){ printf("+");printf("%dx^%d",p->coef,p->exp);}elseprintf("%dx^%d",p->coef,p->exp);p=p->next;}printf("\n");hb=Creat2polynode();p=hb->next;printf("输出多项式B:");if(p->exp==0)printf("%d",p->coef);else printf("%dx^%d",p->coef,p->exp); p=p->next;while(p!=NULL){ if(p->coef>0){ printf("+");printf("%dx^%d",p->coef,p->exp);}elseprintf("%dx^%d",p->coef,p->exp);p=p->next;}printf("\n");hc=subpolynode(ha,hb);p=hc->next;printf("输出差多项式:");if(p->exp==0)printf("%d",p->coef);elseprintf("%dx^%d",p->coef,p->exp); p=p->next;while(p!=NULL){ if(p->coef>0){ printf("+");printf("%dx^%d",p->coef,p->exp);}elseprintf("%dx^%d",p->coef,p->exp);p=p->next;}printf("\n");hd=addpolynode(ha,hb);p=hd->next;printf("输出和多项式:");if(p->exp==0)printf("%d",p->coef);elseprintf("%dx^%d",p->coef,p->exp);p=p->next;while(p!=NULL){ if(p->coef>0){ printf("+");printf("%dx^%d",p->coef,p->exp);}elseprintf("%dx^%d",p->coef,p->exp);p=p->next;}printf("\n");}polynode *Creat1polynode(){ polynode *s,*r,*ha;int m,n;ha=(polynode*)malloc(sizeof(polynode));r=ha;printf("请输入系数m和指数n: ");scanf("%d,%d",&m,&n);while(m!=0){ s=(polynode *)malloc(sizeof(polynode));s->coef=m;s->exp=n;r->next=s;r=s;printf("请输入系数m和指数n: ");scanf("%d,%d",&m,&n);}r->next=NULL;return(ha);}polynode *Creat2polynode(){ polynode *s,*r,*hb;int m,n;hb=(polynode*)malloc(sizeof(polynode));r=hb;printf("请输入系数m和指数n: "); scanf("%d,%d",&m,&n);while(m!=0) { s=(polynode *)malloc(sizeof(polynode));s->coef=m;s->exp=n;r->next=s;r=s;printf("请输入系数m和指数n: ");scanf("%d,%d",&m,&n);}r->next=NULL;return(hb);}polynode *subpolynode(polynode *ha,polynode *hb){ polynode *hc,*p,*q,*s,*r;int sum;p=ha->next;q=hb->next;hc=(polynode*)malloc(sizeof(polynode));r=hc;while(p!=NULL&&q!=NULL){ if(p->exp==q->exp){ sum=p->coef-q->coef;if(sum!=0){ s=(polynode *)malloc(sizeof(polynode));s->coef=sum;s->exp=p->exp;r->next=s;r=s;}p=p->next;q=q->next;}else{ if(p->exp<q->exp){ s=(polynode *)malloc(sizeof(polynode));s->coef=p->coef;s->exp=p->exp;r->next=s;r=s;p=p->next;}else{ s=(polynode *)malloc(sizeof(polynode));s->coef=0-q->coef;s->exp=q->exp;r->next=s;r=s;q=q->next;}}}while(p!=NULL){ s=(polynode *)malloc(sizeof(polynode));s->coef=p->coef;s->exp=p->exp;r->next=s;r=s;p=p->next;}while(q!=NULL){ s=(polynode *)malloc(sizeof(polynode));s->coef=0-q->coef;s->exp=q->exp;r->next=s;r=s;q=q->next;}r->next=NULL;return(hc);}polynode *addpolynode(polynode *ha,polynode *hb){ polynode *p,*q,*pre,*r;int sum;p=ha->next;q=hb->next;pre=ha;while(p!=NULL&&q!=NULL){ if(p->exp<q->exp){ pre->next=p;pre=pre->next;p=p->next;}else if(p->exp==q->exp) { sum=p->coef+q->coef;if(sum!=0){ p->coef=sum;pre->next=p;pre=pre->next;p=p->next;r=q;q=q->next;free(r);}else{ r=p->next;free(p);p=r;r=q->next;free(q);q=r;}}else{ pre->next=q;pre=pre->next;q=q->next;}}while(p!=NULL){ pre->next=p;pre=pre->next;p=p->next;}while(q!=NULL){ pre->next=q;pre=pre->next;q=q->next;}pre->next=NULL;return(ha);}5.测试结果实验一实验二。

《数据结构与算法》课件 第3章 链表

《数据结构与算法》课件 第3章 链表

练习
1、链表中逻辑上相邻的元素在物理上()相邻。 2、已知带头结点的单链表L,指针p指向链表中的一个节点, 指针q指向链表外的节点,在指针p的后面插入q的语句序 列( ) 3、设某非空单链表,要删除指针p所指的结点的直接后继结 点,则需要执行下述语句序列: p=q->next; ( );free(p); 4、线性表的存储有顺序存储和( )存储两种。 5、线性表中哪些元素只有一个直接前驱和一个直接后继? A 首元素 b 尾元素 c 中间的元素 d 所有的元素 6、线性表的各元素之间是()关系 A 层次 b 网状 c 有序 d 集合 7、在单链表中一个结点有()个指针,在双向链表中的一 个结点有()指针
2、求长度 L 21 18 p k p
30
p
75
p
42
p
56 ∧
p p
6 5 4 3 2 1 0
int list_length(LinkList L) {int n=0; LinkList p=L->next; while(p!=NULL) { n++;p=p->next;} return n; }
exit(0);}
s=(SNode *) malloc(sizeof(SNode)); sdata=x; snext=prenext; prenext=s; }
5、删除算法的实现
void LinkListDelete(LinkList L,int i)
……..
ai-1
ai
ai+1
……..
P
相互之间的关系是靠其中的后继地址来表示的
动态链表:根据实际需要临时分配
结构描述如下: typedef struct SNode{ ElemType data; struct SNode *next; //指向结构体类型指针 }*LinkList;

实验3 线性表的链式存储讲解

实验3 线性表的链式存储讲解

实验报告三线性表的链式存储一、实验目的:(1)掌握单链表的基本操作的实现方法。

(2)掌握循环单链表的基本操作实现。

(3)掌握两有序链表的归并操作算法。

二、实验内容:(请采用模板类及模板函数实现)1、线性表链式存储结构及基本操作算法实现[实现提示] (同时可参见教材p64-p73页的ADT描述及算法实现及ppt)函数、类名称等可自定义,部分变量请加上学号后3位。

也可自行对类中所定义的操作进行扩展。

所加载的库函数或常量定义:(1)单链表存储结构类的定义:template <class datatype> class LinkList; //前视定义,便于使用友元template <class datatype>class Node{ friend class LinkList<datatype>; //友元类private:datatype data;Node<datatype> *next; //此处<datatype>也可以省略}template <class datatype>class LinkList{public:LinkList( ); //建立只有头结点的空链表LinkList(datatype a[ ], int n); //建立有n个元素的单链表~LinkList(){} //析构函数,释放整个链表空间int Length(); //求单链表的长度datatype Get(int i); //取单链表中第i个结点的元素值void Insert(int i, datatype x); //在单链表中第i个位置插入元素值为x的结点 void destroy() //在单链表中删除所有的结点void PrintList( ); //遍历单链表,按序号依次输出各元素int Empty() //判断表是否为空private:Node<datatype> *head; //单链表的头指针};(2)初始化带头结点空单链表构造函数实现输入:无前置条件:无动作:初始化一个带头结点的空链表输出:无后置条件:头指针指向头结点。

线性表的链式存储结构

线性表的链式存储结构

1
2
3
4 89
5
10
11
6
7
12
13 14 15
第三层上(i=3),有23-1=4个节点。 第四层上(i=4),有24-1=8个节点。
21
(2) 二叉树的基本性质
A、 二叉树的第i层上至多有2 i-1(i 1)个结点。 B、 深度为h的二叉树中至多含有2h-1个结点。
1
2
3
4 89
5
10
11
6
7
6
7
n0=8 n2=7
8
9 10
11 12
13 14 15
23
(3)满二叉树
1
2
3
4
5
6
7
8
9 10
11 12
13 14 15
特点:每一层上都含有最大结点数。
24
(4)完全二叉树
1
2
4
5
3
6
7
8 9 10 11 12
1
2
4
5
3
6
7
8 9 10 11
12
完全二叉树
非完全二叉树
特点:除最后一层外,每一层都取最大结点数,
左子树 为空
二叉树的五种基本形态
左右子树 均非空
19
二叉数是n(n0)个结点的有限集合。它或为空 数(n=0),或由一个根结点和两棵分别称为根的左子 树和右子树的互不相交的二叉数组成。
特别要注意:二叉数不是树的特殊情况。
a
a
b
b
两棵不同的二叉数
20
(2) 二叉树的基本性质
A、 二叉树的第i层上至多有2 i-1(i 1)个结点。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
L->head->next=p->next;//删除p结点
free(p);//释放p结点占据的存储空间
}
}
(4)求链表L的长度
int ListLength(LINK_LISTL)
{
NODE *p;
int len;
for(p=L.head, len=0;p->next==NULL; p=p->next,len++);
链式存储结构的特点
(1)线性表中的数据元素在存储单元中的存放顺序与逻辑顺序不一定一致;
(2)在对线性表操作时,只能通过头指针进入链表,并通过每个结点的指针域向后扫描其余结点,这样就会造成寻找第一个结点和寻找最后一个结点所花费的时间不等,具有这种特点的存取方式被称为顺序存取方式。
在C语言中,实现线性表的链式存储结构的类型定义
return(len);
}
(5)判链表L空否。
int IsEmpty(LINK_LIST L)
{
if (L.head->next==NULL) return TRUE;
else return FALSE;
}
(6)通过e返回链表L中第i个数据元素的内容
void GetElem(LINK_LIST L,int i,EntryType *e)
typedef strcut node{//结点类型
EntryType item;
struct node *next;
}NODE;
typedef struct{//链表类型
NODE *head;
}LINK_LIST;
典型操作的算法实现
(1)初始化链表L
intInitList(LINK_LIST *L)
NODE *LocateELem(LINK_LIST L,EntryType e)
{
NODE *p;
for (p=L.head->next;p&&p->item!=e;p=p->next);//寻找满足条件的结点
return(p);
}
(8)返回链表L中结点e的直接前驱结点
NODE *PriorElem(LINK_LIST L,NODE* e)
线性表的链式存储结构
线性表的应用举例
线性表顺序存储结构的特点
它是一种简单、方便的存储方式。它要求线性表的数据元素依次存放在连续的存储单元中,从而利用数据元素的存储顺序表示相应的逻辑顺序,这种存储方式属于静态存储形式。
暴露的问题
在做插入或删除元素的操作时,会产生大量的数据元素移动;
对于长度变化较大的线性表,要一次性地分配足够的存储空间,但这些空间常常又得不到充分的利用;
存储地址
内容
直接后继存储地址
100
b
120
...
...
...
首元素位置
120
c
160
...
...
..
144
a
100
...
...
...
160
d
NULL
...
...
...
术语
表示每个数据元素的两部分信息组合在一起被称为结点;
其中表示数据元素内容的部分被称为数据域(data);
表示直接后继元素存储地址的部分被称为指针或指针域(next)。
{
NODE *p;
while (L->head){//依次删除链表中的所有结点
p=L->head; L->head=L->head->next;
free(p);
}
}
(3)清空链表L
voidClearList(LINK_LIST *L)
{
NODE *p;
while (L->head->next){
p=L->head->next;//p指向链表中头结点后面的第一个结点
{
NODE *p;
if (L.head->next==e) return NULL;//检测第一个结点
for (p=L.head;p->next&&p->next!=e;p=p->next);
if (p->next==e) return p;
esle return NULL;
}
(9)返回链表L中结点e的直接后继结点
NODE *NextElem(LINK_LIST L,NODE* e)
{
NODE *p;
for(p=L.head->next;p&&p!=e;p=p->next);
if (p) p=p->next;
return p;
}
(10)在链表L中第i个数据元素之前插入数据元素e
int ListInsert(LINK_LIST *L,int i,EntryType e)
{
NODE *p;
int j;
if (i<1||i>ListLength(L)) exit ERROR;//检测i值的合理性
for (p=L.head,j=0; j!=i;p=p->next,j++);//找到第i个结点
*e=p->item;//将第i个结点的内容赋给e指针所指向的存储单元中
}
(7)在链表L中检索值为e的数据元素
{
NODE *p,*s;
int j;
if (i<1||i>ListLength(L)+1) return ERROR;
s=(NODE*)malloc(sizeof(NODE));
if (s==NULL) return ERROR;
s->item=e;
for (p=L->head,j=0;p&&j<i-1;p=p->next;j++);//寻找第i-1个结点
线性表的容量难以扩充。
第一节 线性表的链式存储结构
线性表的链式存储结构是指用一组任意的存储单元(可以连续,也可以不连续)存储线性表中的数据元素。为了反映数据元素之间的逻辑关系,对于每个数据元素不仅要表示它的具体内容,还要附加一个表示它的直接后继元素存储位置的信息。假设有一个线性表(a,b,c,d),可用下图所示的形式存储:
单链表简化的图形描述形式
其中,head是头指针,它指向单链表中的第一个结点,这是单链表操作的入口点。由于最后一个结点没有直接后继结点,所以,它的指针域放入一个特殊的值NULL。NULL值在图示中常用(^)符号表示。
带头结点的单链表
为了简化对链表的操作,人们经常在链表的第一个结点之前附加一个结点,并称为头结点。这样可以免去对链表第一个结点的特殊处理。如下图所示:
{
L->he存储单元
if (L->head) {L->head->next=NULL;return OK;}
else return ERROR ;
}
(2)销毁链表L
voidDestoryList(LINK_LIST *L)
相关文档
最新文档