数据结构严蔚敏PPT

上传人:m**** 文档编号:568215555 上传时间:2024-07-23 格式:PPT 页数:814 大小:3.72MB
返回 下载 相关 举报
数据结构严蔚敏PPT_第1页
第1页 / 共814页
数据结构严蔚敏PPT_第2页
第2页 / 共814页
数据结构严蔚敏PPT_第3页
第3页 / 共814页
数据结构严蔚敏PPT_第4页
第4页 / 共814页
数据结构严蔚敏PPT_第5页
第5页 / 共814页
点击查看更多>>
资源描述

《数据结构严蔚敏PPT》由会员分享,可在线阅读,更多相关《数据结构严蔚敏PPT(814页珍藏版)》请在金锄头文库上搜索。

1、算法与数据结构算法与数据结构教材教材:数据结构数据结构(C语言版语言版)。严蔚敏,吴伟民。严蔚敏,吴伟民 编编 著。清华大学出版社。著。清华大学出版社。参考文献参考文献: 1 数据结构数据结构 。张选平,雷咏梅。张选平,雷咏梅 编,编, 严蔚敏严蔚敏 审。审。 机械工业出版社。机械工业出版社。 2 数据结构与算法分析。数据结构与算法分析。Clifford A. Shaffer著,著, 张张 铭,刘晓丹铭,刘晓丹 译。电子工业出版社。译。电子工业出版社。 3 数据结构习题与解析数据结构习题与解析(C语实言版语实言版)。李春葆。李春葆。 清华大学出版社。清华大学出版社。 4 数据结构与算法。夏克俭

2、数据结构与算法。夏克俭 编著。国防工业出编著。国防工业出版社。版社。陡冀沛进税厉噶剃嫁纲厉降渺警恃知悍掘溶拇乾盈洛寡沃式怀狗元墟砍函数据结构严蔚敏PPT数据结构严蔚敏PPT第1章 绪 论 目前,计算机已深入到社会生活的各个领域,其应目前,计算机已深入到社会生活的各个领域,其应用已不再仅仅局限于科学计算,而更多的是用于控制,用已不再仅仅局限于科学计算,而更多的是用于控制,管理及数据处理等非数值计算领域。计算机是一门研究管理及数据处理等非数值计算领域。计算机是一门研究用计算机进行信息表示和处理的科学。这里面涉及到两用计算机进行信息表示和处理的科学。这里面涉及到两个问题:信息的个问题:信息的表示表示

3、,信息的,信息的处理处理。 信息的表示和组织又直接关系到处理信息的程序的信息的表示和组织又直接关系到处理信息的程序的效率。随着应用问题的不断复杂,导致信息量剧增与信效率。随着应用问题的不断复杂,导致信息量剧增与信息范围的拓宽,使许多系统程序和应用程序的规模很大,息范围的拓宽,使许多系统程序和应用程序的规模很大,结构又相当复杂。因此,必须分析待处理问题中的对象结构又相当复杂。因此,必须分析待处理问题中的对象的特征及各对象之间存在的关系,这就是数据结构这门的特征及各对象之间存在的关系,这就是数据结构这门课所要研究的问题。课所要研究的问题。缚庶纂粪叠敖辈丸骑咯艳效撰中虚衅彦之埠砒俊都氟镐晶吩胁荚淖醉

4、余夷数据结构严蔚敏PPT数据结构严蔚敏PPT编写解决实际问题的程序的一般过程编写解决实际问题的程序的一般过程: 如何用数据形式描述问题如何用数据形式描述问题?即由问题抽象出一个即由问题抽象出一个适当的数学模型适当的数学模型; 问题所涉及的数据量大小及数据之间的关系问题所涉及的数据量大小及数据之间的关系; 如何在计算机中存储数据及体现数据之间的关系如何在计算机中存储数据及体现数据之间的关系? 处理问题时需要对数据作何种运算处理问题时需要对数据作何种运算? 所编写的程序的性能是否良好所编写的程序的性能是否良好?上面所列举的问题基本上由数据结构这门课程来回答。上面所列举的问题基本上由数据结构这门课程

5、来回答。计算机求解问题的一般步骤计算机求解问题的一般步骤汾戮官思妓损眯鹰苑电腔寝榔认贿蹭店粗敏描眶姑锰并所蛰奴硝膘语撞败数据结构严蔚敏PPT数据结构严蔚敏PPT1.1 数据结构及其概念数据结构及其概念 算法与数据结构算法与数据结构是计算机科学中的一门综合性专是计算机科学中的一门综合性专业基础课业基础课。是。是介于数学、计算机硬件、计算机软件三者介于数学、计算机硬件、计算机软件三者之间的一门核心课程,不仅是一般程序设计的基础,而之间的一门核心课程,不仅是一般程序设计的基础,而且是设计和实现编译程序、操作系统、数据库系统及其且是设计和实现编译程序、操作系统、数据库系统及其他系统程序和大型应用程序的

6、重要基础。他系统程序和大型应用程序的重要基础。奎蹄烤疲闻俱钡耳劫狭颓罚暗赔宗喜淤忠瘟赡况赢围翼声妹哭札相税像鲍数据结构严蔚敏PPT数据结构严蔚敏PPT1.1.1 数据结构的例子数据结构的例子姓名姓名电话号码电话号码陈海陈海13612345588李四锋李四锋13056112345。例例1:电话号码查询系统:电话号码查询系统 设有一个电话号码薄,它记录了设有一个电话号码薄,它记录了N个人的名字和其个人的名字和其相应的电话号码,假定按如下形式安排:相应的电话号码,假定按如下形式安排:(a1, b1),(a2, b2),(an, bn),其中其中ai, bi(i=1,2n) 分别表示分别表示某人的名字

7、和电话号码。某人的名字和电话号码。 本问题是一种典型的表格问题本问题是一种典型的表格问题。如表如表1-1,数据与数据成简单的一对一的,数据与数据成简单的一对一的线性关系线性关系。表表1-1 线性表结构线性表结构缺咽很服着猪摩基惧拨肚隙她桐侍纫雨抛谷掐涡魁霜落犁啸悬植抠魏营窖数据结构严蔚敏PPT数据结构严蔚敏PPT例例2:磁盘目录文件系统:磁盘目录文件系统 磁盘根目录下有很多子目录磁盘根目录下有很多子目录及文件,每个子目录里又可以包及文件,每个子目录里又可以包含多个子目录及文件,但每个子含多个子目录及文件,但每个子目录只有一个父目录,依此类推目录只有一个父目录,依此类推: 本问题是一种典型的树型

8、结本问题是一种典型的树型结构问题,如图构问题,如图1-1 ,数据与数据,数据与数据成一对多的关系,是一种典型的成一对多的关系,是一种典型的非线性关系结构非线性关系结构树形结构树形结构。图图图图1-11-1 树形树形结构结构结构结构惺真拟贴鼎惠办咆模缩收条新份始崔厄犯朵糕彬隅司蹲舶婉朗腋踏园魔惑数据结构严蔚敏PPT数据结构严蔚敏PPT例例3:交通网络图:交通网络图 从一个地方到另外一个地方可以有多条路径从一个地方到另外一个地方可以有多条路径。本问本问题是一种典型的题是一种典型的网状结构网状结构问题,数据与数据成多对多的问题,数据与数据成多对多的关系,是一种非线性关系结构关系,是一种非线性关系结构

9、。佛山惠州广州中山东莞深圳珠海图图1-2 网状结构网状结构蛰茂苫领旋译它秆粉切鸥逛佐努悉伏恰肖小贞往鄙迁歧衅尊藐解黎垛徒瓣数据结构严蔚敏PPT数据结构严蔚敏PPT 数据数据(Data) :是客观事物的符号表示。在计算机科:是客观事物的符号表示。在计算机科学中指的是所有能输入到计算机中并被计算机程序处理学中指的是所有能输入到计算机中并被计算机程序处理的符号的总称。的符号的总称。 数据元素数据元素(Data Element) :是数据的基本单位,在:是数据的基本单位,在程序中通常程序中通常作为一个整体作为一个整体来进行考虑和处理。来进行考虑和处理。 一个数据元素可由若干个一个数据元素可由若干个数据

10、项数据项(Data Item)组成。组成。数据项是数据的不可分割的最小单位。数据项是对客观数据项是数据的不可分割的最小单位。数据项是对客观事物某一方面特性的数据描述。事物某一方面特性的数据描述。 数据对象数据对象(Data Object):是性质相同的数据元素的集:是性质相同的数据元素的集合,是数据的一个子集。如字符集合合,是数据的一个子集。如字符集合C=A,B,C, 。1.1.2 基本概念和术语基本概念和术语象膏恫吮熟钨疙调娟计步渺诗搔腋鄙崭摄郁擒天羔板秘煞禁鬃涛科唉跑既数据结构严蔚敏PPT数据结构严蔚敏PPT 数据结构数据结构(Data Structure):是指相互之间具有:是指相互之间

11、具有(存存在在)一定联系一定联系(关系关系)的数据元素的集合。元素之间的相的数据元素的集合。元素之间的相互联系互联系(关系关系)称为称为逻辑结构逻辑结构。数据元素之间的逻辑结构。数据元素之间的逻辑结构有四种基本类型,如图有四种基本类型,如图1-3所示。所示。 集合集合:结构中的数据元素除了:结构中的数据元素除了“同属于一个集合同属于一个集合”外,没有其它关系。外,没有其它关系。 线性结构线性结构:结构中的数据元素之间存在一对一的:结构中的数据元素之间存在一对一的关系。关系。 树型结构树型结构:结构中的数据元素之间存在一对多的:结构中的数据元素之间存在一对多的关系。关系。 图状结构或网状结构图状

12、结构或网状结构:结构中的数据元素之间存:结构中的数据元素之间存在多对多的关系。在多对多的关系。卫墅度蔽粪斯畴嚣丧鳞咋量虐纪右敞渺脏残链佛尉账抠颧佬糕勉永痢粗沁数据结构严蔚敏PPT数据结构严蔚敏PPT 数据结构的形式定义是一个二元组:数据结构的形式定义是一个二元组: Data-Structure=(D,S)其中:其中:D是数据元素的有限集,是数据元素的有限集,S是是D上关系的有限集。上关系的有限集。例例2:设数据逻辑结构:设数据逻辑结构B=(K,R) K=k1, k2, , k9 R= , 画出这逻辑结构的图示,并确定那些是起点,那些是终点画出这逻辑结构的图示,并确定那些是起点,那些是终点1.1

13、.3 数据结构的形式定义数据结构的形式定义图图1-3 四类基本四类基本结构图结构图结构图结构图琴匣耀椰鹊括画括武翼醋娱即襄成耻躬炭诗拖芳狱黄黎樟蛊剃疲挞诌疆辈数据结构严蔚敏PPT数据结构严蔚敏PPT1.1.4 数据结构的存储方式数据结构的存储方式 数据元素之间的关系可以是元素之间代表某种含义数据元素之间的关系可以是元素之间代表某种含义的自然关系,也可以是为处理问题方便而人为定义的关的自然关系,也可以是为处理问题方便而人为定义的关系,这种系,这种自然或人为定义的自然或人为定义的 “关系关系”称为数据元素之称为数据元素之间的间的逻辑关系逻辑关系,相应的,相应的结构结构称为称为逻辑结构逻辑结构。 数

14、据结构在计算机内存中的存储包括数据结构在计算机内存中的存储包括数据元素的数据元素的存储存储和和元素之间的关系的表示元素之间的关系的表示。 元素之间的关系在计算机中有两种不同的表示方法:元素之间的关系在计算机中有两种不同的表示方法:顺序表示和非顺序表示顺序表示和非顺序表示。由此得出两种不同的存储结构:由此得出两种不同的存储结构:顺序存储结构顺序存储结构和和链式存储结构链式存储结构。 顺序存储结构顺序存储结构:用数据元素在存储器中的相对位置用数据元素在存储器中的相对位置来表示数据元素之间的逻辑结构来表示数据元素之间的逻辑结构(关系关系)。措殉困肋琢深琐明希襄枫仗漆绒掸顶广蚁频津罩览跺巾磨壹骄灼夷慑

15、妈镊数据结构严蔚敏PPT数据结构严蔚敏PPT 链式存储结构链式存储结构:在每一个数据元素中增加一个存放在每一个数据元素中增加一个存放另一个元素地址的指针另一个元素地址的指针(pointer ),用该指针来表示,用该指针来表示数据元素之间的逻辑结构数据元素之间的逻辑结构(关系关系)。例例:设有数据集合设有数据集合A=3.0,2.3,5.0,-8.5,11.0 ,两种不同,两种不同的存储结构。的存储结构。 顺序结构:数据元素存放的顺序结构:数据元素存放的地址是连续的地址是连续的; 链式结构:数据元素存放的链式结构:数据元素存放的地址是否连续没有要地址是否连续没有要求求。 数据的逻辑结构和物理结构是

16、密不可分的两个方面,数据的逻辑结构和物理结构是密不可分的两个方面,一个一个算法的设计取决于算法的设计取决于所选定的所选定的逻辑结构逻辑结构,而,而算法的实算法的实现依赖于现依赖于所采用的所采用的存储结构存储结构。 在在C语言中,用语言中,用一维数组一维数组表示顺序存储结构表示顺序存储结构;用用结结构体类型构体类型表示链式存储结构。表示链式存储结构。纷驱病咀锁宪毁碱眷旦阁锁淌刹琴辣蔽底德涡嘶侨穆垂岔哭仁炭愚黑景砖数据结构严蔚敏PPT数据结构严蔚敏PPT数据结构的三个组成部分:数据结构的三个组成部分:逻辑结构逻辑结构: 数据元素之间逻辑关系的描述数据元素之间逻辑关系的描述 D_S=(D,S)存储结

17、构存储结构: 数据元素在计算机中的存储及其逻辑数据元素在计算机中的存储及其逻辑关系的表现称为数据的存储结构或物理结构关系的表现称为数据的存储结构或物理结构。数据操作数据操作: 对数据要进行的运算对数据要进行的运算。 本课程中将要讨论的三种逻辑结构及其采用的存储本课程中将要讨论的三种逻辑结构及其采用的存储结构如图结构如图1-4所示。所示。袍琼洛漱避亏换缆寄磋哥瀑戊讼钞涤幌吁谓侠蹬叁察辟滚箕倍雨昌边北怎数据结构严蔚敏PPT数据结构严蔚敏PPT数据的逻辑结构数据的逻辑结构非线性结构非线性结构集合图状结构有向图无向图树形结构一般树二叉树线性结构线性结构一般线性表线性表推广广义表数组串受限线性表栈和队列

18、图1-5 数据逻辑结构层次关系图数据逻辑结构层次关系图图图1-4 逻辑结构与所采用的存储结构逻辑结构与所采用的存储结构线性表线性表树树图图顺序存储结构顺序存储结构链式存储结构链式存储结构复合存储结构复合存储结构逻辑结构逻辑结构物理结构物理结构民申啃洽请蕊抵汽为翰噎忙泉殃涵键娩贸逗稿蓟栏去市哩曾藻甭局都隧嗡数据结构严蔚敏PPT数据结构严蔚敏PPT 数据类型数据类型(Data Type):指的是:指的是一个值的集合一个值的集合和定和定义在义在该值集上的一组操作该值集上的一组操作的总称。的总称。 数据类型是和数据结构密切相关的一个概念。数据类型是和数据结构密切相关的一个概念。 在在C语言中数据类型有

19、:基本类型和构造类型。语言中数据类型有:基本类型和构造类型。 数据结构不同于数据类型,也不同于数据对象,它数据结构不同于数据类型,也不同于数据对象,它不仅要描述数据类型的数据对象,而且要描述数据对象不仅要描述数据类型的数据对象,而且要描述数据对象各元素之间的相互关系。各元素之间的相互关系。1.1.5 数据类型数据类型幂厩猜舷友抑谈林驴奖鼓辩十奄傣残柠嘻朔哩磺逼彝瑟簇蚜仑斧琴枉牟魁数据结构严蔚敏PPT数据结构严蔚敏PPT 数据结构的主要运算包括:数据结构的主要运算包括: 建立建立(Create)一个数据结构;一个数据结构; 消除消除(Destroy)一个数据结构;一个数据结构; 从一个数据结构中

20、删除从一个数据结构中删除(Delete)一个数据元素;一个数据元素; 把一个数据元素插入把一个数据元素插入(Insert)到一个数据结构中;到一个数据结构中; 对一个数据结构进行访问对一个数据结构进行访问(Access); 对一个数据结构对一个数据结构(中的数据元素中的数据元素)进行修改进行修改(Modify); 对一个数据结构进行排序对一个数据结构进行排序(Sort); 对一个数据结构进行查找对一个数据结构进行查找(Search)。1.1.6 数据结构的运算数据结构的运算旅辩猛哟庸宇睫映逆醚炽兵娃京难仟哎障留容誊麓唐晰逃黎腆澡将邦措棠数据结构严蔚敏PPT数据结构严蔚敏PPT 抽象数据类型抽象

21、数据类型(Abstract Data Type ,简称,简称ADT):是指一个数学模型以及定义在该模型上的一组操作。是指一个数学模型以及定义在该模型上的一组操作。 ADT的定义仅是一组逻辑特性描述,的定义仅是一组逻辑特性描述, 与其在计算与其在计算机内的表示和实现无关。因此,不论机内的表示和实现无关。因此,不论ADT的内部结构如的内部结构如何变化,只要其数学特性不变,都不影响其外部使用。何变化,只要其数学特性不变,都不影响其外部使用。 ADT的形式化定义是三元组:的形式化定义是三元组:ADT=(D,S,P)其中:其中:D是是数据对象数据对象,S是是D上的上的关系集关系集,P是对是对D的的基本基

22、本操作集操作集。1.2 抽象数据类型抽象数据类型碎屑唐污达惺鬼沽尤葵稠喇当犊屿坯渊砒韧咕响沈程难舆这梨惑巨涤股途数据结构严蔚敏PPT数据结构严蔚敏PPTADT的一般定义形式是:的一般定义形式是:ADT 数据对象:数据对象: 数据关系:数据关系: 基本操作:基本操作: ADT 其中数据对象和数据关系的定义用伪码描述。其中数据对象和数据关系的定义用伪码描述。 基本操作的定义是:基本操作的定义是:()初始条件:初始条件: 操作结果:操作结果: 惑谋患腿阀芳队册瘦链茵牟限迄解沉怖瞥绽棺昭牧毗田翘邑仔了纠寇碗澄数据结构严蔚敏PPT数据结构严蔚敏PPT 初始条件:描述操作执行之前数据结构和参数应初始条件:

23、描述操作执行之前数据结构和参数应满足的条件满足的条件;若不满足,则操作失败,返回相应的出若不满足,则操作失败,返回相应的出错信息。错信息。 操作结果:描述操作正常完成之后,数据结构的操作结果:描述操作正常完成之后,数据结构的变化状况和变化状况和 应返回的结果。应返回的结果。纂癸煮涂莉宦桨呻珍掘形疽荧奄重循粒俱误忆淘冬憨闯俗刷链市娩振碑绢数据结构严蔚敏PPT数据结构严蔚敏PPT1.3.1 算法算法算法算法(Algorithm):是对特定问题求解方法:是对特定问题求解方法(步骤步骤)的一种的一种描述,是指令的有限序列,其中每一条指令表示一个或描述,是指令的有限序列,其中每一条指令表示一个或多个操作

24、。多个操作。算法具有以下五个特性算法具有以下五个特性 有穷性有穷性: 一个算法必须总是在执行有穷步之后结一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。束,且每一步都在有穷时间内完成。 确定性确定性:算法中每一条指令必须有确切的含义。:算法中每一条指令必须有确切的含义。不存在二义性。且算法只有一个入口和一个出口。不存在二义性。且算法只有一个入口和一个出口。 可行性可行性: 一个算法是能行的。即算法描述的操作一个算法是能行的。即算法描述的操作都可以通过已经实现的基本运算执行有限次来实现。都可以通过已经实现的基本运算执行有限次来实现。1.3 算法分析初步算法分析初步爱跃续抱演痘挤

25、弘棕阅灶说攫攻闸首妨倡俄块袍峨材贩怜胰哈圆零整烃殿数据结构严蔚敏PPT数据结构严蔚敏PPT 输入输入: 一个算法有零个或多个输入,这些输入取一个算法有零个或多个输入,这些输入取自于某个特定的对象集合。自于某个特定的对象集合。 输出输出: 一个算法有一个或多个输出,这些输出是一个算法有一个或多个输出,这些输出是同输入有着某些特定关系的量。同输入有着某些特定关系的量。 一个算法可以用多种方法描述,主要有:使用自然一个算法可以用多种方法描述,主要有:使用自然语言描述;使用形式语言描述;使用计算机程序设计语语言描述;使用形式语言描述;使用计算机程序设计语言描述。言描述。 算法和程序是两个不同的概念算法

26、和程序是两个不同的概念。一个计算机程序是。一个计算机程序是对一个算法使用某种程序设计语言的具体实现。算法必对一个算法使用某种程序设计语言的具体实现。算法必须可终止意味着不是所有的计算机程序都是算法。须可终止意味着不是所有的计算机程序都是算法。 在本门课程的学习、作业练习、上机实践等环节,在本门课程的学习、作业练习、上机实践等环节,算法都用算法都用C语言来描述。在上机实践时,为了检查算法语言来描述。在上机实践时,为了检查算法是否正确,应编写成完整的是否正确,应编写成完整的C语言程序。语言程序。肿滁弹刹巩鸦术洱漱顷陡讲丽侍胰舱昧淹坏臣泥珐遁旁披笺苛输滚品冒柬数据结构严蔚敏PPT数据结构严蔚敏PPT

27、评价一个好的算法有以下几个标准评价一个好的算法有以下几个标准 正确性正确性(Correctness ): 算法应满足具体问题的算法应满足具体问题的需求。需求。 可读性可读性(Readability): 算法应容易供人阅读和算法应容易供人阅读和交流。可读性好的算法有助于对算法的理解和修改。交流。可读性好的算法有助于对算法的理解和修改。 健壮性健壮性(Robustness): 算法应具有容错处理。当算法应具有容错处理。当输入非法或错误数据时,算法应能适当地作出反应输入非法或错误数据时,算法应能适当地作出反应或进行处理,而不会产生莫名其妙的输出结果。或进行处理,而不会产生莫名其妙的输出结果。 通用性

28、通用性(Generality): 算法应具有一般性算法应具有一般性 ,即,即算法的处理结果对于一般的数据集合都成立。算法的处理结果对于一般的数据集合都成立。1.3.2 算法设计的要求算法设计的要求澈暇翅耸跃何掣伴粳怎绰懂诗姑署下韭磅业埋候楔吵升雨颐谷虽崔甥量桅数据结构严蔚敏PPT数据结构严蔚敏PPT 算法执行时间需通过依据该算法编制的程序在计算算法执行时间需通过依据该算法编制的程序在计算机上运行所消耗的时间来度量。其方法通常有两种:机上运行所消耗的时间来度量。其方法通常有两种:事后统计事后统计:计算机内部进行执行时间和实际占用空间的:计算机内部进行执行时间和实际占用空间的统计。统计。 问题:必

29、须先运行依据算法编制的程序;依赖软硬问题:必须先运行依据算法编制的程序;依赖软硬件环境,容易掩盖算法本身的优劣;没有实际价值。件环境,容易掩盖算法本身的优劣;没有实际价值。事前分析事前分析:求出该算法的一个时间界限函数。:求出该算法的一个时间界限函数。1.3.3 算法效率的度量算法效率的度量 效率与存储量需求效率与存储量需求: 效率指的是算法执行的时间;效率指的是算法执行的时间;存储量需求指算法执行过程中所需要的最大存储空存储量需求指算法执行过程中所需要的最大存储空间。一般地,这两者与问题的规模有关。间。一般地,这两者与问题的规模有关。啮典弓辕失晒屁餐酶敏灼带式洗菩砾崇票谗舞毅瘫鲜叮缺贸阳博谐

30、缠戒钱数据结构严蔚敏PPT数据结构严蔚敏PPT与此相关的因素有:与此相关的因素有: 依据算法选用何种策略;依据算法选用何种策略; 问题的规模;问题的规模; 程序设计的语言;程序设计的语言; 编译程序所产生的机器代码的质量;编译程序所产生的机器代码的质量; 机器执行指令的速度;机器执行指令的速度; 撇开软硬件等有关部门因素,可以认为一个特定算撇开软硬件等有关部门因素,可以认为一个特定算法法“运行工作量运行工作量”的大小,只依赖于问题的规模(通常的大小,只依赖于问题的规模(通常用用n表示),或者说,它表示),或者说,它是问题规模的函数是问题规模的函数。殊鹅尿勒娩焙跳档甸绕暗吵宋矿翌喇粗末郝腻西谁异

31、框差兄床邓塞担靡肃数据结构严蔚敏PPT数据结构严蔚敏PPT算法分析应用举例算法分析应用举例 算法中算法中基本操作重复执行的次数基本操作重复执行的次数是问题规模是问题规模n的某的某个函数,其时间量度记作个函数,其时间量度记作 T(n)=O(f(n),称作算法的渐,称作算法的渐近时间复杂度近时间复杂度(Asymptotic Time complexity),简称,简称时间时间复杂度复杂度。 一般地,常用一般地,常用最深层循环内最深层循环内的语句中的原操作的的语句中的原操作的执执行频度行频度(重复执行的次数重复执行的次数)来表示。来表示。 “O”的定义:的定义: 若若f(n)是正整数是正整数n的一个

32、函数,则的一个函数,则 O(f(n)表示表示 M0 ,使得当,使得当n n0时,时,| f(n) | M | f(n0) | 。表示表示时间复杂度时间复杂度的阶有:的阶有: O(1) :常量时间阶:常量时间阶 O (n):线性时间阶:线性时间阶 O(n) :对数时间阶:对数时间阶 O(nn) :线性对数时间阶:线性对数时间阶惑诞昆臻候瑟您襟葱肖榜兵璃媒刮狗耿妖煞隆樱挤疲辙筛札剔适业寺戚砰数据结构严蔚敏PPT数据结构严蔚敏PPT O (nk): k2 ,k次方时间阶次方时间阶例例 两个两个n阶方阵的乘法阶方阵的乘法 for(i=1,i=n; +i) for(j=1; j=n; +j) cij=0

33、 ; for(k=1; k=n; +k) cij+=aik*bkj ; 由于是一个三重循环,每个循环从由于是一个三重循环,每个循环从1到到n,则总次数为:,则总次数为: nnn=n3时间复杂度为时间复杂度为T(n)=O(n3)例例 +x; s=0 ; 将将x自增看成是基本操作,则语句频度为,即时自增看成是基本操作,则语句频度为,即时间复杂度为间复杂度为(1) 。膳倚绰跪岔二烹厩碉她乒胖酒瞪弄练迷劝度藕挨贼倪应鸦镐终纺医典闺禁数据结构严蔚敏PPT数据结构严蔚敏PPT如果将如果将s=0也看成是基本操作,则语句频度为,其时也看成是基本操作,则语句频度为,其时间复杂度仍为间复杂度仍为(1),即常量阶。

34、,即常量阶。例例 for(i=1; i=n; +i) +x; s+=x ; 语句频度为:语句频度为:2n,其时间复杂度为:,其时间复杂度为:O(n) ,即为线性,即为线性阶。阶。例例 for(i=1; i=n; +i)for(j=1; j=n; +j) +x; s+=x ; 语句频度为:语句频度为:2n2 ,其时间复杂度为:,其时间复杂度为:O(n2) ,即为平,即为平方阶。方阶。 诀宁烦轰记忠杰测魔歉渝圾痉捡豁钡帖呢饿虞毕涝沁倍故赴辅齿芍声悠料数据结构严蔚敏PPT数据结构严蔚敏PPT定理定理:若若A(n)=a m n m +a m-1 n m-1 +a1n+a0是一个是一个m次多项式,则次多

35、项式,则A(n)=O(n m)例例 for(i=2;i=n;+i) for(j=2;j=i-1;+j) +x; ai,j=x; 语句频度为:语句频度为: 1+2+3+n-2=(1+n-2) (n-2)/2 =(n-1)(n-2)/2 =n2-3n+2 时间复杂度为时间复杂度为O(n2),即此算法的时间复杂度为平方,即此算法的时间复杂度为平方阶。阶。 一个算法时间为一个算法时间为O(1)的算法,它的基本运算执行的算法,它的基本运算执行的次数是固定的。因此,总的时间由一个常数(即的次数是固定的。因此,总的时间由一个常数(即零次多项式)来限界。而一个时间为零次多项式)来限界。而一个时间为O(n2)的

36、算法则的算法则由一个二次多项式来限界。由一个二次多项式来限界。炬心赐刨幅鼓煎解法娠润败芋重壶蛙谗否堰寸在坠毅荐郭皖钨酉统姆您礁数据结构严蔚敏PPT数据结构严蔚敏PPT 以下六种计算算法时间的多项式是最常用的。其关以下六种计算算法时间的多项式是最常用的。其关系为:系为: O(1)O(n)O(n)O(nn)O(n2)O(n3) 指数时间的关系为:指数时间的关系为: O(2n)O(n!)O(nn) 当当n取得很大时,指数时间算法和多项式时间算法取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊。因此,只要有人能将现有指数在所需时间上非常悬殊。因此,只要有人能将现有指数时间算法中的任何一个算

37、法化简为多项式时间算法,那时间算法中的任何一个算法化简为多项式时间算法,那就取得了一个伟大的成就。就取得了一个伟大的成就。 有的情况下,算法中基本操作重复执行的次数还有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同。随问题的输入数据集不同而不同。焚计莆矣烛政枣媳匹纠辐姨贬递厄国诲掣亏剧车阴术渠揽送渠补婉掘敬京数据结构严蔚敏PPT数据结构严蔚敏PPT例例1:素数的判断算法。素数的判断算法。Void prime( int n)/* n是一个正整数是一个正整数 */ int i=2 ; while ( (n% i)!=0 & i*1.0sqrt(n) )printf(“&d 是

38、一个素数是一个素数n” , n) ;elseprintf(“&d 不是一个素数不是一个素数n” , n) ; 嵌套的最深层语句是嵌套的最深层语句是i+;其频度由条件;其频度由条件( (n% i)!=0 & i*1.0 sqrt(n) ) 决定,显然决定,显然i*1.01 & change; -i)for (j=0; jaj+1) aj aj+1 ; change=TURE ; 最好情况:最好情况:0次次 最坏情况:最坏情况:1+2+3+ +n-1=n(n-1)/2 平均时间复杂度为:平均时间复杂度为: O(n2) 该到酞者狭画琢耪涉戮瞬越颐碴右踊终夏拄颤猾鳞龟怨饮泛虚模骂吕卑喂数据结构严蔚敏P

39、PT数据结构严蔚敏PPT1.3.4 算法的空间分析算法的空间分析 空间复杂度空间复杂度(Space complexity) :是指算法编写成:是指算法编写成程序后,在计算机中运行时所需存储空间大小的度量。程序后,在计算机中运行时所需存储空间大小的度量。记作:记作: S(n)=O(f(n) 其中:其中: n为问题的规模为问题的规模(或大小或大小)该存储空间一般包括三个方面:该存储空间一般包括三个方面: 指令常数变量所占用的存储空间指令常数变量所占用的存储空间; 输入数据所占用的存储空间输入数据所占用的存储空间; 辅助辅助(存储存储)空间。空间。 一般地,算法的一般地,算法的空间复杂度空间复杂度指

40、的是指的是辅助空间辅助空间。 一维数组一维数组an: 空间复杂度空间复杂度 O(n) 二维数组二维数组anm: 空间复杂度空间复杂度 O(n*m)垄度前晴释柏魏钵蚂赠节虏辫辕伶宅桨抖认蒜旧壤硒撼闻叶猴则泣绢荷槛数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 一一1 简要回答术语:数据,数据元素,数据结构,数据简要回答术语:数据,数据元素,数据结构,数据类型。类型。2 数据的逻辑结构?数据的物理结构?逻辑结构与物数据的逻辑结构?数据的物理结构?逻辑结构与物理结构的区别和联系是什么?理结构的区别和联系是什么?3 数据结构的主要运算包括哪些?数据结构的主要运算包括哪些?4 算法分析的目的是什么?

41、算法分析的主要方面是什算法分析的目的是什么?算法分析的主要方面是什么?么?5 分析以下程序段的时间复杂度,请说明分析的理由分析以下程序段的时间复杂度,请说明分析的理由或原因。或原因。 捧棺搭曼吹器艾莲娩郡毅倚杭溯打六瘁叙酸缠挣搐湖疑殴接被鳖辨筋俄迅数据结构严蔚敏PPT数据结构严蔚敏PPTSum1( int n ) int p=1, sum=0, m ;for (m=1; m=n; m+) p*=m ; sum+=p ; return (sum) ;Sum2( int n ) int sum=0, m, t ;for (m=1; m=n; m+) p=1 ; for (t=1; t=m; t+)

42、 p*=t ;sum+=p ; return (sum) ; 递归函数递归函数fact( int n ) if (n0时,将非空的线性表记作:时,将非空的线性表记作: (a1,a2,an) a1称为线性表的称为线性表的第一个第一个( (首首) )结点,结点,an称为线性表的称为线性表的最后最后一个一个( (尾尾) )结点。结点。2.1.1 线性表的定义线性表的定义樟住湛莆锰背搏衰告肠皑被紫瘟内鲸换偿够恳妇颅稍馏钙区亩岂尖叭拼煮数据结构严蔚敏PPT数据结构严蔚敏PPTa1,a2,ai-1都是都是ai(2in)的的前驱前驱,其中,其中ai-1是是ai的的直直接前驱接前驱;ai+1,ai+2,an都

43、是都是ai(1i n-1)的的后继后继,其中,其中ai+1是是ai的的直接后继直接后继。2.1.2 线性表的逻辑结构线性表的逻辑结构 线性表中的数据元素线性表中的数据元素ai所代表的具体含义随具体应所代表的具体含义随具体应用的不同而不同,在线性表的定义中,只不过是一个抽用的不同而不同,在线性表的定义中,只不过是一个抽象的表示符号。象的表示符号。 线性表中的线性表中的结点结点可以是可以是单值元素单值元素(每个元素只有一每个元素只有一个数据项个数据项) 。例例1: 26个英文字母组成的字母表:个英文字母组成的字母表: (A,B,C、Z)躇蚤败续菊砚弱仕臭惮笔铅谭驮蝴症劫贬蛇抑禽迄框呵敝竭拆堰攫遍怨

44、势数据结构严蔚敏PPT数据结构严蔚敏PPT例例2 : 某校从某校从1978年到年到1983年各种型号的计算机拥有量年各种型号的计算机拥有量的变化情况:的变化情况:(6,17,28,50,92,188)例例3 : 一副扑克的点数一副扑克的点数 (2,3,4,J,Q,K,A) 线性表中的线性表中的结点结点可以是可以是记录型记录型元素,每个元素含元素,每个元素含有多个数据项有多个数据项 ,每个项称为结点的一个域,每个项称为结点的一个域 。每个元。每个元素有一个可以唯一标识每个结点的素有一个可以唯一标识每个结点的数据项组数据项组,称为,称为关键字关键字。例例4 : 某校某校2001级同学的基本情况:级

45、同学的基本情况:(2001414101,张里户张里户,男男,06/24/1983), (2001414102,张化司张化司,男男,08/12/1984) , (2001414102,李利辣李利辣,女女,08/12/1984) 若线性表中的结点是若线性表中的结点是按值按值(或按关键字值或按关键字值)由小到由小到大大(或由大到小或由大到小)排列排列的,称线性表是有序的。的,称线性表是有序的。穷尽饮腥爸排臆笋捉你染窒蚊茧醛世装菊母浓西上际襄冻献旺魏荫剐散续数据结构严蔚敏PPT数据结构严蔚敏PPT2.1.3 线性表的抽象数据类型定义线性表的抽象数据类型定义ADT List数据对象:数据对象:D = a

46、i | aiElemSet, i=1,2,n, n0 数据关系:数据关系:R = | ai-1, aiD, i=2,3,n 基本操作:基本操作:InitList( &L )操作结果:构造一个空的线性表操作结果:构造一个空的线性表L; 线性表是一种相当灵活的数据结构,其长度可根线性表是一种相当灵活的数据结构,其长度可根据需要增长或缩短。据需要增长或缩短。 对线性表的数据元素可以访问、插入和删除。对线性表的数据元素可以访问、插入和删除。猿棱猾藉仙浙侍肪曝扇缉牵卡宿挨羚淬黔豹隶学芯哀惹索咋磕身扰怀玲替数据结构严蔚敏PPT数据结构严蔚敏PPTListLength( L )初始条件:线性表初始条件:线性

47、表L已存在;已存在;操作结果:若操作结果:若L为空表,则返回为空表,则返回TRUE,否则返回,否则返回FALSE;.GetElem( L, i, &e )初始条件:线性表初始条件:线性表L已存在,已存在,1iListLength(L);操作结果:用操作结果:用e返回返回L中第中第i个数据元素的值;个数据元素的值;ListInsert ( L, i, &e )初始条件:线性表初始条件:线性表L已存在,已存在,1iListLength(L) ;操作结果:在线性表操作结果:在线性表L中的第中的第i个位置插入元素个位置插入元素e; ADT List按躯谣惶底欠缓翱没专茨炬抽呸懈券涧检密袍商造信趴军摊誊

48、邵佯营跑属数据结构严蔚敏PPT数据结构严蔚敏PPT2.2 线性表的顺序存储线性表的顺序存储 顺序存储顺序存储 :把线性表的结点:把线性表的结点按逻辑顺序按逻辑顺序依次存放在依次存放在一组地址连续的存储单元一组地址连续的存储单元里。用这种方法存储的线性表里。用这种方法存储的线性表简称顺序表。简称顺序表。顺序存储顺序存储的线性表的的线性表的特点特点: 线性表的逻辑顺序与物理顺序一致线性表的逻辑顺序与物理顺序一致; 数据元素之间的关系是以元素在计算机内数据元素之间的关系是以元素在计算机内“物理物理位置相邻位置相邻”来体现。来体现。 设有非空的线性表:设有非空的线性表:(a1,a2,an) 。顺序存储

49、如。顺序存储如图图2-1所示。所示。2.2.1 线性表的顺序存储结构线性表的顺序存储结构秩拥值佯吐凛抡蔗钩伙磐落玲周问础孝雅木井凋懒服逗猿铱巾疚直虾捍辰数据结构严蔚敏PPT数据结构严蔚敏PPT 在具体的机器环境下在具体的机器环境下:设线性表的每个元素需占用:设线性表的每个元素需占用l个存储单元,以所占的第一个单元的存储地址作为数据个存储单元,以所占的第一个单元的存储地址作为数据元素的存储位置。则线性表中第元素的存储位置。则线性表中第i+1个数据元素的存储位个数据元素的存储位置置LOC(ai+1)和第和第i个数据元素的存储位置个数据元素的存储位置LOC(ai)之间满之间满足下列关系:足下列关系:

50、 LOC(ai+1)=LOC(ai)+l 线性表的第线性表的第i个数据元素个数据元素ai的存储位置为:的存储位置为: LOC(ai)=LOC(a1)+(i-1)*l a1 a2 ai an Loc(a1) Loc(ai)+(i-1)* l 图图2-1 线性表的顺序存储表示线性表的顺序存储表示菏咽淘辐询踢勃氖尼陶情漱拭揽农喻溪崇朵泼傍某瘁礼柿椭靡臀橡狭凋厘数据结构严蔚敏PPT数据结构严蔚敏PPT 在高级语言在高级语言( (如如C C语言语言) )环境下环境下:数组具有随机存取:数组具有随机存取的特性的特性,因此,借助数组来描述顺序表。除了用数组来,因此,借助数组来描述顺序表。除了用数组来存储线性

51、表的元素之外,顺序表还应该有表示线性表的存储线性表的元素之外,顺序表还应该有表示线性表的长度属性,所以用结构类型来定义顺序表类型。长度属性,所以用结构类型来定义顺序表类型。#define OK 1#define ERROR -1#define MAX_SIZE 100typedef int Status ;typedef int ElemType ; typedef struct sqlist ElemType Elem_arrayMAX_SIZE ;int length ; SqList ;宏欲伴混得戚禾育终什骄粮口志沾弓砰站纤洋铲莲吱妇朱恐返窥捷瞧消吟数据结构严蔚敏PPT数据结构严蔚敏PP

52、T2.2.2 顺序表的基本操作顺序表的基本操作 顺序存储结构中,很容易实现线性表的一些操作:顺序存储结构中,很容易实现线性表的一些操作:初始化、赋值、查找、修改、插入、删除、求长度等初始化、赋值、查找、修改、插入、删除、求长度等。以下将对几种主要的操作进行讨论以下将对几种主要的操作进行讨论。1 顺序线性表初始化顺序线性表初始化 Status Init_SqList( SqList *L ) L-elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ;if ( !L - elem_array ) return ERROR ;

53、else L-length= 0 ; return OK ; 瞪聪胖沸屉雌永唤窟经羞战奎庄沂畅惭籽咒吓若仪除场净碍儒刺庙粗牵珊数据结构严蔚敏PPT数据结构严蔚敏PPT2 顺序顺序线性表的插入线性表的插入 在线性表在线性表 L= (a1,a i-1,ai, ai+1,an) 中中的的第第i(1in)个位置上插入一个新结点个位置上插入一个新结点e,使其成为线性,使其成为线性表表: L=(a1,a i-1,e,ai,ai+1,an) 实现步骤实现步骤(1)(1) 将线性表将线性表L中的中的第第i个至第个至第n个结点后移一个位置。个结点后移一个位置。(2) (2) 将结点将结点e插入到结点插入到结点a

54、i-1之后之后。 (3) (3) 线性表长度加线性表长度加1。蹋矫芥洁狱镍幸钙狱凶六美酪伯鹊县棺帅输授绽痕副生蠕售甫谚毗猪顺策数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述Status Insert_SqList(Sqlist *L,int i ,ElemType e) int j ;if ( iL-length-1) return ERROR ;if (L-length=MAX_SIZE) printf(“线性表溢出线性表溢出!n”); return ERROR ; for ( j=L-length1; j=i-1; -j )L-Elem_arrayj+1=L-Elem_array

55、j;/* i-1位置以后的所有结点后移位置以后的所有结点后移 */L-Elem_arrayi-1=e; /* 在在i-1位置插入结点位置插入结点 */L-length+ ;return OK ; 拂硕旬捅汲瑟蓑捶营鹏疟静往胚务澡贺良们刺中迹伶侧忆肇什础葡悯权浪数据结构严蔚敏PPT数据结构严蔚敏PPT 时间复杂度分析时间复杂度分析 在线性表在线性表L中的中的第第i个个元素之前插入新结点,其时间元素之前插入新结点,其时间主要耗费在表中结点的移动操作上,因此,可用结点的主要耗费在表中结点的移动操作上,因此,可用结点的移动来估计算法的时间复杂度。移动来估计算法的时间复杂度。 设设在线性表在线性表L中的

56、中的第第i个个元素之前插入结点的概率元素之前插入结点的概率为为Pi,不失一般性,设各个位置插入是等概率,则,不失一般性,设各个位置插入是等概率,则Pi=1/(n+1),而插入时移动结点的次数为,而插入时移动结点的次数为n-i+1。总的平均移动次数:总的平均移动次数: Einsert=pi*(n-i+1) (1in) Einsert=n/2 。 即即在顺序表上做插入运算,平均要移动表上一半结在顺序表上做插入运算,平均要移动表上一半结点。当表长点。当表长n较大时,算法的效率相当低。因此算法的较大时,算法的效率相当低。因此算法的平均时间复杂度为平均时间复杂度为O(n)。惑血里屯吱预伊微荫膝钥穿率威斩

57、音瞅握渣工炙茸酣荡屯辩幻批捂升宠沛数据结构严蔚敏PPT数据结构严蔚敏PPT3 顺序线性表的删除顺序线性表的删除 在线性表在线性表 L=(a1,a i-1,ai, ai+1,an) 中删中删除结点除结点ai(1in),使其成为线性表,使其成为线性表: L= (a1,ai-1,ai+1,an) 实现步骤实现步骤(1)(1) 将线性表将线性表L中的中的第第i+1个至第个至第n个结点依此向前移个结点依此向前移动一个位置。动一个位置。(2) (2) 线性表长度减线性表长度减1。算法描述算法描述ElemType Delete_SqList(Sqlist *L,int i) int k ; ElemType

58、 x ;福筑谴呆辱程桃心挥禾藩儒届习胶沾泽痉弹纫井笛户悍愿苏末奴蓝孰励帕数据结构严蔚敏PPT数据结构严蔚敏PPTif (L-length=0) printf(“线性表线性表L为空为空!n”); return ERROR; else if ( iL-length ) printf(“要删除的数据元素不存在要删除的数据元素不存在!n”) ; return ERROR ; else x=L-Elem_arrayi-1 ; /*保存结点的值保存结点的值*/for ( k=i ; klength ; k+) L-Elem_arrayk-1=L-Elem_arrayk; /* i位置以后的所有结点前移位置

59、以后的所有结点前移 */L-length-; return (x); 序祁蹲弓藻偿知梁旁供桥填椒婿念瓷褥巳纳怖罢申淄毒夏贵怂紊朵螟瘟瑟数据结构严蔚敏PPT数据结构严蔚敏PPT 时间复杂度分析时间复杂度分析 删除线性表删除线性表L中的中的第第i个个元素,其时间主要耗费在表元素,其时间主要耗费在表中结点的移动操作上,因此,可用结点的移动来估计算中结点的移动操作上,因此,可用结点的移动来估计算法的时间复杂度。法的时间复杂度。 设设在线性表在线性表L中中删除第删除第i个个元素的概率为元素的概率为Pi,不失,不失一般性,设删除各个位置是等概率,则一般性,设删除各个位置是等概率,则Pi=1/n,而删除,而

60、删除时移动结点的次数为时移动结点的次数为n-i。则总的平均移动次数:则总的平均移动次数: Edelete=pi*(n-i) (1in) Edelete=(n-1)/2 。 即即在顺序表上做删除运算,平均要移动表上一半结在顺序表上做删除运算,平均要移动表上一半结点。当表长点。当表长n较大时,算法的效率相当低。因此算法的较大时,算法的效率相当低。因此算法的平均时间复杂度为平均时间复杂度为O(n)。绒掳愧潍闽常硒扬承喘欠童惫弘窄寝沼独炳蚤拳筷炬说愚迅赶琶越串忘妨数据结构严蔚敏PPT数据结构严蔚敏PPT4 顺序线性表的查找定位删除顺序线性表的查找定位删除 在线性表在线性表 L= (a1,a2,an)

61、中删除值为中删除值为x的第一的第一个结点个结点。实现步骤实现步骤(1)(1) 在线性表在线性表L查找值为查找值为x的第的第一个数据元素。一个数据元素。(2) (2) 将从找到的位置至最后一将从找到的位置至最后一个结点依次向前移动一个结点依次向前移动一个位置。个位置。 (3) (3) 线性表长度减线性表长度减1。算法描述算法描述Status Locate_Delete_SqList(Sqlist *L,ElemType x) /* 删除线性表删除线性表L中值为中值为x的的第第一个一个结点结点 */ int i=0 , k ; 缴扯蜗溪橇氖邀辖钎踊豢辽半伶议拜芝柳伤缕益黍专霹念沏蝉雹总更播鬼数据结

62、构严蔚敏PPT数据结构严蔚敏PPTwhile (ilength) /*查找值为查找值为x的的第第一个一个结点结点*/ if (L-Elem_arrayi!=x ) i+ ; else for ( k=i+1; klength; k+) L-Elem_arrayk-1=L-Elem_arrayk; L-length-; break ; if (iL-length) printf(“要删除的数据元素不存在要删除的数据元素不存在!n”) ; return ERROR ; return OK; 津秒鸟虱切涝手柳何攻妇铅吧拯刮巾酿努清擂渡粗孟旧辜特斜娶皇烯锗营数据结构严蔚敏PPT数据结构严蔚敏PPT 时

63、间复杂度分析时间复杂度分析 时间主要耗费在数据元素的比较和移动操作上。时间主要耗费在数据元素的比较和移动操作上。首先,首先,在线性表在线性表L中查找值为中查找值为x的的结点是否存在结点是否存在;其次,若其次,若值为值为x的的结点存在,且在结点存在,且在线性表线性表L中的位置为中的位置为i ,则在,则在线性表线性表L中删除中删除第第i个个元素。元素。 设设在线性表在线性表L删除删除数据元素概率为数据元素概率为Pi,不失一般性,不失一般性,设各个位置是等概率,则设各个位置是等概率,则Pi=1/n。 比较的平均次数比较的平均次数: Ecompare=pi*i (1in) Ecompare=(n+1)

64、/2 。 删除时平均移动次数删除时平均移动次数:Edelete=pi*(n-i) (1in) Edelete=(n-1)/2 。 平均时间复杂度:平均时间复杂度:Ecompare+Edelete=n ,即为即为O(n)顿膘本接仓雨浮菩残往湘卓挂旬绽臀拧眶略厉职鸥豁谢一叭怔缴肉菩鲁卿数据结构严蔚敏PPT数据结构严蔚敏PPT2.3 线性表的链式存储线性表的链式存储 2.3.1 线性表的链式存储结构线性表的链式存储结构 链式存储链式存储 :用用一组任意的存储单元存储一组任意的存储单元存储线性表中线性表中的数据元素。用这种方法存储的线性表简称的数据元素。用这种方法存储的线性表简称线性链表线性链表。 存

65、储链表中结点的一组任意的存储单元可以是连续存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。意位置上的。 链表中结点的逻辑顺序和物理顺序不一定相同。链表中结点的逻辑顺序和物理顺序不一定相同。哑钩柔币达鬃告鄙陶恨季曝他婚遵羚琼栗欺什瓜吉咒柜森霄赠酪堰妮拦糯数据结构严蔚敏PPT数据结构严蔚敏PPT 为了正确表示结点间的逻辑关系,在存储每个结点为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址值的同时,还必须存储指示其直接后继结点的地址( (或或位置位置) ),

66、称为指针,称为指针(pointer)或链或链(link),这两部分组成,这两部分组成了链表中的结点结构,如图了链表中的结点结构,如图2-2所示。所示。 链表是通过每个结点的指针域将线性表的链表是通过每个结点的指针域将线性表的n个结点个结点按其逻辑次序链接在一起的。按其逻辑次序链接在一起的。 每一个结只包含一个指针域的链表,称为单链表。每一个结只包含一个指针域的链表,称为单链表。 为操作方便,总是在链表的第一个结点之前附设一为操作方便,总是在链表的第一个结点之前附设一个头结点个头结点( (头指针头指针) )head指向第一个结点。头结点的数据指向第一个结点。头结点的数据域可以不存储任何信息域可以

67、不存储任何信息( (或链表长度等信息或链表长度等信息) )。data next图图2-2 链表结点结构链表结点结构data :数据域,存放结点的值。:数据域,存放结点的值。next :指针:指针域,存放结点的直接后继的地址。域,存放结点的直接后继的地址。糠逼蒋药萤李咨牲腿雕丛演荔馋储淆肢啼祟南烩帮抛排庇札滇筹琅咨代最数据结构严蔚敏PPT数据结构严蔚敏PPT 3695headfat1100bat1300cat1305eat3700hatNULL1100370013001305bat cat eat fat hat head 图图2-3 带头结点的单链表的逻辑状态、物理存储方式带头结点的单链表的逻

68、辑状态、物理存储方式 单链表是由表头唯一确定,因此单单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名。链表可以用头指针的名字来命名。例例1 1、线性表、线性表L=(bat,cat,eat,fat,hat)其其带头结点的单带头结点的单链表的逻辑状态和物理链表的逻辑状态和物理存储方式如图存储方式如图2-3所示。所示。既音枉祸榆乔毗搭竭抑挫押绑技学靠汰弄剔诗湖承脆既槐词城蜗琴荫叁筹数据结构严蔚敏PPT数据结构严蔚敏PPT1 结点的描述与实现结点的描述与实现 C语言中用语言中用带指针的结构体类型带指针的结构体类型来描述来描述typedef struct Lnode ElemType data

69、; /*数据域,保存结点的值数据域,保存结点的值 */struct Lnode *next; /*指针域指针域*/LNode; /*结点的类型结点的类型 */2 结点的实现结点的实现 结点是通过动态分配和释放来的实现结点是通过动态分配和释放来的实现,即需要时分,即需要时分配,不需要时释放。实现时是分别使用配,不需要时释放。实现时是分别使用C语言提供的标语言提供的标准函数:准函数:malloc() ,realloc(),sizeof() ,free() 。构似隆瘁拌极汤独启斑怔菇兢莫想霉愿吼遵趾踩量侈细烈诲着踊芭鄙芒缘数据结构严蔚敏PPT数据结构严蔚敏PPT动态分配动态分配 p=(LNode*)

70、malloc(sizeof(LNode);函数函数malloc分配了一个类型为分配了一个类型为LNode的结点变量的空间,的结点变量的空间,并将其首地址放入指针变量并将其首地址放入指针变量p中。中。动态释放动态释放 free(p) ;系统回收由指针变量系统回收由指针变量p所指向的内存区。所指向的内存区。P必须是最近一必须是最近一次调用次调用malloc函数时的返回值。函数时的返回值。3 最常用的基本操作及其示意图最常用的基本操作及其示意图 结点的赋值结点的赋值 LNode *p;p=(LNode*)malloc(sizeof(LNode); p-data=20; p-next=NULL ;p2

71、0NULL害吠簿具真纫镊镐夯矢瞄谎君沿右膝拇玻戮翻盾戏新惟督洞睫涛相敞麻锨数据结构严蔚敏PPT数据结构严蔚敏PPT 常见的指针操作常见的指针操作 q=p ;pa操作前paq操作后 q=p-next ;bpa操作前操作后qbpa p=p-next ;bpa操作前操作后pba q-next=p ;cpbqa操作前操作后qbacp(a)终熬也葫骋瞅驻挞哥雷咀蓑弥龟釜势遗环绞庚倍搭岂逆吱忆境材耶鸭瘴汀数据结构严蔚敏PPT数据结构严蔚敏PPT q-next=p-next ;(a)xypbqa操作前操作后qbaxyp操作前ypxbqa操作后ypxbqa(b)操作前ypxbqa操作后ypxbqa(b)亦柏翁

72、赎派努麦慧残协锅厕锦看萨闭墨蒸吟淄括扶束轧掖故速矽闪候程敦数据结构严蔚敏PPT数据结构严蔚敏PPT2.3.2 单线性链式的基本操作单线性链式的基本操作1 建立单链表建立单链表 假设线性表中结点的数据类型是整型,以假设线性表中结点的数据类型是整型,以32767作作为结束标志。动态地建立单链表的常用方法有如下两种:为结束标志。动态地建立单链表的常用方法有如下两种:头插入法头插入法,尾插入法尾插入法。 头插入法建表头插入法建表 从一个空表开始,重复读入数据,生成新结点,从一个空表开始,重复读入数据,生成新结点,将读入数据存放到新结点的数据域中,然后将新结点插将读入数据存放到新结点的数据域中,然后将新

73、结点插入到当前链表的表头上,直到读入结束标志为止。即入到当前链表的表头上,直到读入结束标志为止。即每每次插入的结点都作为链表的第一个结点次插入的结点都作为链表的第一个结点。例嚷掌萎慕贪彤啄酌狡特吁健盒诗历再泥颊蔡哩漳淤肺攫鱼撮禹翠镑岛闷数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述LNode *create_LinkList(void) /* 头插入法创建单链表头插入法创建单链表,链表的头结点链表的头结点head作为返回值作为返回值 */ int data ;LNode *head, *p;head= (LNode *) malloc( sizeof(LNode);head-next

74、=NULL; /* 创建链表的表头结点创建链表的表头结点head */ while (1) scanf(“%d”, &data) ;if (data=32767) break ;p= (LNode *)malloc(sizeof(LNode);pdata=data; /* 数据域赋值数据域赋值 */予寒瓤城紧舟市版嘘淀广循蹄曝骗桨纫铆溅遥瓮慷泻蒂坦绰缔繁袁流涡也数据结构严蔚敏PPT数据结构严蔚敏PPTpnext=headnext ; headnext=p ; /* 钩链钩链,新创建,新创建的结点总是作为第一个结点的结点总是作为第一个结点 */return (head);(2) 尾插入法建表尾插

75、入法建表 头插入法建立链表虽然算法简单,但生成的链表中头插入法建立链表虽然算法简单,但生成的链表中结点的次序和输入的顺序相反。若希望二者次序一致,结点的次序和输入的顺序相反。若希望二者次序一致,可采用尾插法建表。该方法是将可采用尾插法建表。该方法是将新结点插入到当前链表新结点插入到当前链表的表尾,使其成为当前链表的尾结点的表尾,使其成为当前链表的尾结点。旗碍绑跨袁茬节绞汽蛹包柄骄付腮还炔漱孩秋衣痢热呀晓娟芍敦围镶时迭数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述LNode *create_LinkList(void) /* 尾插入法创建单链表尾插入法创建单链表,链表的头结点链表的头结

76、点head作为返回值作为返回值 */ int data ;LNode *head, *p, *q;head=p=(LNode *)malloc(sizeof(LNode); p-next=NULL; /* 创建单链表的表头结点创建单链表的表头结点head */while (1) scanf(“%d”,& data);if (data=32767) break ;q= (LNode *)malloc(sizeof(LNode); qdata=data; /* 数据域赋值数据域赋值 */qnext=pnext; pnext=q; p=q ; 鸯弹绽酚郡吝牛谨闽淋葡丧哀共刽丰雇鹅会咎蓄镭敌叉恬圭托苛

77、定刁础嘉数据结构严蔚敏PPT数据结构严蔚敏PPT /*钩链钩链,新创建,新创建的结点总是作为最后一个结点的结点总是作为最后一个结点*/return (head); 无论是哪种插入方法,如果要插入建立的单线性无论是哪种插入方法,如果要插入建立的单线性链表的结点是链表的结点是n个,算法的时间复杂度均为个,算法的时间复杂度均为O(n)。 对于单链表,无论是哪种操作,只要涉及到钩链对于单链表,无论是哪种操作,只要涉及到钩链( (或重新钩链或重新钩链) ),如果,如果没有明确给出直接后继没有明确给出直接后继,钩链,钩链( (或或重新钩链重新钩链) )的次序必须是的次序必须是“先右后左先右后左”。益隶以呻

78、泣宴长孕拔旅噬斟愁纱磐眷镊颓并颖股烽宿涵奋于霹讶香郑陨龚数据结构严蔚敏PPT数据结构严蔚敏PPT2 单链表的查找单链表的查找(1) 按序号查找按序号查找 取单链表中的第取单链表中的第i个元素。个元素。 对于单链表,不能象顺序表中那样直接按序号对于单链表,不能象顺序表中那样直接按序号i访访问结点,而只能从链表的头结点出发,沿链域问结点,而只能从链表的头结点出发,沿链域next逐个逐个结点往下搜索,直到搜索到第结点往下搜索,直到搜索到第i个结点为止。因此,个结点为止。因此,链链表不是随机存取结构表不是随机存取结构。 设单链表的长度为设单链表的长度为n,要查找表中第,要查找表中第i个结点,仅个结点,

79、仅当当1in时,时,i的值是合法的。的值是合法的。龋拱夹笼燃刀贡鄙葡摈晴褐尘让瘪弘帆掇扩燕肤胺匈囤试氯靠民无昌缨甄数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述ElemType Get_Elem(LNode *L , int i) int j ; LNode *p;p=L-next; j=1; /* 使使p指向第一个结点指向第一个结点 */while (p!=NULL & jnext; j+; /* 移动指针移动指针p , j计数计数 */if (j!=i) return(-32768) ;else return(p-data); /* p为为NULL 表示表示i太大太大; ji表示

80、表示i为为0 */移动指针移动指针p的频度:的频度:in:n次。次。时间复杂度时间复杂度: O(n)。绷杯芭拔事蹄亭蜗叠滔匡框山澡梆犀展诽皮群琵韦乳翠幼阳臼境毡你酶骂数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 按值查找按值查找 按值查找是在链表中,查找是否有结点值等于给定按值查找是在链表中,查找是否有结点值等于给定值值key的结点的结点? ? 若有,则返回首次找到的值为若有,则返回首次找到的值为key的结点的结点的存储位置;否则返回的存储位置;否则返回NULL。查找时从开始结点出发,。查找时从开始结点出发,沿链表逐个将结点的值和给定值沿链表逐个将结点的值和给定值key作比较。作比较。琴瓮呀

81、摘渴智陈厚凡沂尊涡浴呐捧匣镍隆拜迂涉螟鸣醋暂募浚厌迅骑显葡数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述LNode *Locate_Node(LNode *L,int key)/* 在以在以L为头结点的单链表中查找值为为头结点的单链表中查找值为key的第一个结点的第一个结点 */ LNode *p=Lnext;while ( p!=NULL& pdata!=key) p=pnext;if (pdata=key) return p;else printf(“所要查找的结点不存在所要查找的结点不存在!n”); retutn(NULL); 算法的执行与形参算法的执行与形参key有关,平均时

82、间复杂度为有关,平均时间复杂度为O(n)。梳盈愿延己细匡丙峪敏课韵抽惰偿些丁弘丙宿晓转棺弧纲振册幢掀铂畅鹿数据结构严蔚敏PPT数据结构严蔚敏PPT3 单链表的插入单链表的插入 插入运算是将值为插入运算是将值为e的新结点插入到表的第的新结点插入到表的第i个结个结点的位置上,即插入到点的位置上,即插入到ai-1与与ai之间。因此,必须首先找之间。因此,必须首先找到到ai-1所在所在的结点的结点p,然后生成一个数据域为,然后生成一个数据域为e的新结点的新结点q,q结点作为结点作为p的直接后继结点。的直接后继结点。算法描述算法描述void Insert_LNode(LNode *L,int i,Ele

83、mType e) /* 在以在以L为头结点的单链表的第为头结点的单链表的第i个位置插入值为个位置插入值为e的结点的结点 */ int j=0; LNode *p,*q;p=Lnext ;while ( p!=NULL& jnext; j+; 裸撑贫曾诡撑秒阂茂盼躇拔营拜哉沏配梢悯窿刷雀清她涤渗劈兑速锰富贬数据结构严蔚敏PPT数据结构严蔚敏PPTif (j!=i-1) printf(“i太大或太大或i为为0!n ”); else q=(LNode *)malloc(sizeof(LNode);qdata=e; qnext=pnext;pnext=q; 设链表的长度为设链表的长度为n,合法的插入位

84、置是,合法的插入位置是1in。算。算法的时间主要耗费法的时间主要耗费移动指针移动指针p上,故时间复杂度亦为上,故时间复杂度亦为O(n)。耗议舵必淘楔介影溃拿暂墩篇氧例纹昨状吁哑磨浮订扶汤背限乌讣甫原峰数据结构严蔚敏PPT数据结构严蔚敏PPT4 单链表的删除单链表的删除 按序号删除按序号删除 删除单链表中的第删除单链表中的第i个结点。个结点。 为了删除第为了删除第i个结点个结点ai,必须找到结点的存储地址。,必须找到结点的存储地址。该存储地址是在其直接前趋结点该存储地址是在其直接前趋结点ai-1的的next域中,因此,域中,因此,必须首先找到必须首先找到ai-1的存储位置的存储位置p,然后令,然

85、后令pnext指向指向ai的的直接后继结点,即把直接后继结点,即把ai从链上摘下。最后释放结点从链上摘下。最后释放结点ai的的空间,将其归还给空间,将其归还给“存储池存储池”。 设单链表长度为设单链表长度为n,则删去第,则删去第i个结点仅当个结点仅当1in时时是合法的。则当是合法的。则当i=n+1时,虽然被删结点不存在,但其时,虽然被删结点不存在,但其前趋结点却存在,是终端结点。故判断条件之一是前趋结点却存在,是终端结点。故判断条件之一是pnext!=NULL。显然此算法的时间复杂度也是。显然此算法的时间复杂度也是O(n)(n)。 锨橙相谎藩因腊刻曾阀兆壤蹬柏碎妹蚁搁伴担惨纵硝乏予饵宅洗乡浩殊

86、焉数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述void Delete_LinkList(LNode *L, int i) /* 删除以删除以L为头结点的单链表中的第为头结点的单链表中的第i i个结点个结点 */ int j=1; LNode *p,*q;p=L; q=L-next;while ( p-next!=NULL& jnext; j+; if (j!=i) printf(“i太大或太大或i为为0!n ”); else pnext=qnext; free(q); 认傍折颅习扒蛆欧氟索纫伶蹋追逆韭酥臣庸春虎堕疵蕊福峰镑效补个纱搔数据结构严蔚敏PPT数据结构严蔚敏PPT 按值删除

87、按值删除 删除单链表中值为删除单链表中值为key的第一个结点。的第一个结点。 与按值查找相类似,首先要查找值为与按值查找相类似,首先要查找值为keykey的结点是的结点是否存在否存在? ? 若存在,则删除;否则返回若存在,则删除;否则返回NULL。修獭腋靳讶荣巨闪慨蔽跑鹃巍杠贝嫂揩炙哨蛀烁幼坏糖沈男懂谋贱候变咱数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述void Delete_LinkList(LNode *L,int key)/* 删除以删除以L为头结点的单链表中值为为头结点的单链表中值为key的第一个结点的第一个结点 */ LNode *p=L, *q=Lnext;while

88、( q!=NULL& qdata!=key) p=q; q=qnext; if (qdata=key) p-next=q-next; free(q); else printf(“所要删除的结点不存在所要删除的结点不存在!n”); 嫌阜瞬剃定屑烷糜豁装谁愿顷碘精整竞翔拔趟跺僵蕉劣裸堑体者塞肾雹力数据结构严蔚敏PPT数据结构严蔚敏PPT 算法的执行与形参算法的执行与形参k key有关,平均时间复杂度为有关,平均时间复杂度为O(n)。 从上面的讨论可以看出,链表上实现插入和删除运从上面的讨论可以看出,链表上实现插入和删除运算,无需移动结点,仅需修改指针。解决了顺序表的插算,无需移动结点,仅需修改指针

89、。解决了顺序表的插入或删除操作需要移动大量元素的问题。入或删除操作需要移动大量元素的问题。变形之一:变形之一: 删除单链表中值为删除单链表中值为key的所有结点。的所有结点。 与按值查找相类似,但比前面的算法更简单。与按值查找相类似,但比前面的算法更简单。基本思想基本思想:从从单链表的第一个结点开始,对每个结点单链表的第一个结点开始,对每个结点进行检查,若进行检查,若结点的值为结点的值为keykey,则删除之,然后检查下一,则删除之,然后检查下一个结点,直到所有的结点都检查。个结点,直到所有的结点都检查。 碉仗奏澎吃苞项勇节篙匿观江单秧蜡己招积畦逢窗妄译不粕详湃蔷叼莆只数据结构严蔚敏PPT数据

90、结构严蔚敏PPT算法描述算法描述void Delete_LinkList_Node(LNode *L,int key)/* 删除以删除以L为头结点的单链表中值为为头结点的单链表中值为key的第一个结点的第一个结点 */ LNode *p=L, *q=Lnext;while ( q!=NULL) if (qdata=key) p-next=q-next; free(q); q=p-next; else p=q; q=qnext; 雕室遗猜碧骆权恿郝籽过疽鸵札唁封酗斌嚼脏复坷茧醒离堑那悲矛下漏睦数据结构严蔚敏PPT数据结构严蔚敏PPT变形之二:变形之二: 删除单链表中所有值重复的结点,使得所有结点

91、的删除单链表中所有值重复的结点,使得所有结点的值都不相同。值都不相同。 与按值查找相类似,但比前面的算法更复杂。与按值查找相类似,但比前面的算法更复杂。基本思想基本思想:从从单链表的第一个结点开始,对每个结点单链表的第一个结点开始,对每个结点进行检查:检查链表中该结点的所有后继进行检查:检查链表中该结点的所有后继结点,只要有结点,只要有值和该结点的值相同,则删除之;然后检查下一个结点,值和该结点的值相同,则删除之;然后检查下一个结点,直到所有的结点都检查。直到所有的结点都检查。 洪澡雹傍辆饯牵根似痞迭非象看胖翻衰灿应缕屋喜楚铺责失盘芳切职身框数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法

92、描述void Delete_Node_value(LNode *L)/* 删除以删除以L为头结点的单链表中所有值相同的结点为头结点的单链表中所有值相同的结点 */ LNode *p=L-next, *q, *ptr; while ( p!=NULL) /* 检查链表中所有结点检查链表中所有结点 */ *q=p, *ptr=pnext;/* 检查结点检查结点p的所有后继结点的所有后继结点ptr */while (ptr!=NULL) if (ptrdata=p-data) q-next=ptr-next; free(ptr); ptr=q-next; else q=ptr; ptr=ptrnex

93、t; 闯皆粥草寨幌贰届谨汇原榷诣置尘嘻忽掺伞梅息的枫匙钒唁泥铸乾顺题袍数据结构严蔚敏PPT数据结构严蔚敏PPTp=p-next ; 靠够帐毒昆增椎伯拭辐楼磷吱灰技抹卵醉马涉把晃违琢苍帕嫩独愚金钝艾数据结构严蔚敏PPT数据结构严蔚敏PPT5 单链表的合并单链表的合并 设有两个有序的单链表,它们的头指针分别是设有两个有序的单链表,它们的头指针分别是La 、 Lb,将它们合并为以,将它们合并为以Lc为为头指针的有序链表。合并头指针的有序链表。合并前的示意图如图前的示意图如图2-4所示。所示。15 图图2-4 两个有序的单链表两个有序的单链表La ,Lb的初始状态的初始状态-2 4 9 Lb pb-7

94、 3 12 23 La Lcpapc酿廖钩蜀褪扎嘻婿橱妈伪起巨诸秒桥陌主妊凋亦权顺趋亚味斗玖回簇格绝数据结构严蔚敏PPT数据结构严蔚敏PPT合并了值为合并了值为-7,-2的结点后示意图如图的结点后示意图如图2-5所示。所示。图图2-5 合并了值为合并了值为-7 ,-2的结点后的状态的结点后的状态-2 4 9 15 Lb pcpbLc-7 3 12 23 La pa算法说明算法说明 算法中算法中pa ,pb分别是待考察的两个链表的当前结分别是待考察的两个链表的当前结点,点,pc是合并过程中合并的链表的最后一个结点。是合并过程中合并的链表的最后一个结点。矣霖蚌甲腺莹盼蛋拨拽甭负汹散坑桑尖拱锡憎幢琳

95、净想聋陌壹酉及吓杭犯数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述LNode *Merge_LinkList(LNode *La, LNode *Lb) /* 合并以合并以La, Lb为头结点的两个有序单链表为头结点的两个有序单链表 */ LNode *Lc, *pa , *pb , *pc, *ptr ;Lc=La ; pc=La ; pa=La-next ; pb=Lb-next ; while (pa!=NULL & pb!=NULL) if (pa-datadata) pc-next=pa ; pc=pa ; pa=pa-next ; /* 将将pa所指的结点合并,所指的结点

96、合并,pa指向下一个结点指向下一个结点 */if (pa-datapb-data) pc-next=pb ; pc=pb ; pb=pb-next ; /* 将将pa所指的结点合并,所指的结点合并,pa指向下一个结点指向下一个结点 */烛像糊扩掸烛赃匝旭粕蓖盯绣邑芬薯妆认涅盘迫标剑禽汉乔嚏刮髓惨淀于数据结构严蔚敏PPT数据结构严蔚敏PPTif (pa-data=pb-data) pc-next=pa ; pc=pa ; pa=pa-next ; ptr=pb ; pb=pb-next ; free(ptr) ; /* 将将pa所指的结点合并,所指的结点合并,pb所指结点删除所指结点删除 */

97、if (pa!=NULL) pc-next=pa ;else pc-next=pb ; /*将剩余的结点链上将剩余的结点链上*/free(Lb) ;return(Lc) ;算法分析算法分析 若若La ,Lb两个链表的长度分别是两个链表的长度分别是m,n,则链表合,则链表合并的时间复杂度为并的时间复杂度为O(m+n) 。蜡义踩膀将淤聊岁洞谨崭撤汁湘誉芥派景娥秋轰弛役本澈诀名拾曹西珊掷数据结构严蔚敏PPT数据结构严蔚敏PPT2.3.3 循环链表循环链表 循环链表循环链表(Circular Linked List):是一种头尾相是一种头尾相接的链表。其特点是最后一个结点的指针域指向链表的接的链表。其

98、特点是最后一个结点的指针域指向链表的头结点,整个头结点,整个链表的指针域链接成一个环链表的指针域链接成一个环。 从循环链表的任意一个结点出发都可以找到链表中从循环链表的任意一个结点出发都可以找到链表中的其它结点,使得表处理更加方便灵活。的其它结点,使得表处理更加方便灵活。 图图2-6是带头结点的单循环链表的示意图。是带头结点的单循环链表的示意图。空表空表图图2-6 单循环链表示意图单循环链表示意图非空表非空表a1 a2 anhead head 檄病把删刃识段纠惩售惹褐未囱侧服顽焰皮贾骚键忌渍菏寻嚷棠蚁闺阔郭数据结构严蔚敏PPT数据结构严蔚敏PPT循环链表的操作循环链表的操作 对于单循环链表,除

99、链表的合并外,其它的操作和对于单循环链表,除链表的合并外,其它的操作和单线性链表基本上一致,仅仅需要在单线性链表操作算单线性链表基本上一致,仅仅需要在单线性链表操作算法基础上作以下简单修改:法基础上作以下简单修改: 判断是否是空链表:判断是否是空链表:head-next=head ; ; 判断是否是表尾结点:判断是否是表尾结点:p-next=head ; ;歼萌售桅丢终臣豪秆管绚颗彼咬涎队忻受兆蛰赎靶刊恢滚囚亿春华看毋狠数据结构严蔚敏PPT数据结构严蔚敏PPT2.4 双向链表双向链表 双向链表双向链表(Double Linked List) : :指的是构成链表指的是构成链表的每个结点中设立两

100、个指针域:一个指向其直接前趋的的每个结点中设立两个指针域:一个指向其直接前趋的指针域指针域prior,一个指向其直接后继的指针域,一个指向其直接后继的指针域next。这样。这样形成的链表中有两个方向不同的链,故称为形成的链表中有两个方向不同的链,故称为双向链表双向链表。 和单链表类似,双向链表一般增加头指针也能使双和单链表类似,双向链表一般增加头指针也能使双链表上的某些运算变得方便。链表上的某些运算变得方便。 将头结点和尾结点链接起来也能构成循环链表,并将头结点和尾结点链接起来也能构成循环链表,并称之为双向循环链表。称之为双向循环链表。 双向链表是为了克服单链表的单向性的缺陷而引入双向链表是为

101、了克服单链表的单向性的缺陷而引入的。的。丈湾绍寇秦枝斌绑督洋展蚀浩攫峰欲拿弃涝肇批己师蛊承彼遗锑我露河榴数据结构严蔚敏PPT数据结构严蔚敏PPT1 双向链表的结点及其类型定义双向链表的结点及其类型定义 双向链表的结点的类型定义如下。其结点形式如双向链表的结点的类型定义如下。其结点形式如图图2-7所示所示,带头结点的双向链表的形式如图,带头结点的双向链表的形式如图2-8所示所示。typedef struct Dulnode ElemType data ;struct Dulnode *prior , *next ;DulNode ;data nextprior图图2-7 双向链表结点形式双向链表

102、结点形式非空双向链表非空双向链表heada2a1an空双向链表空双向链表head图图2-8 带头结点的双向链表形式带头结点的双向链表形式獭培讥论痉浸制拼尔外耸超属孵蹭肌氖戚恼偿鼻篡层堂趾簿湘豆匀吧艺跑数据结构严蔚敏PPT数据结构严蔚敏PPT 双向链表结构具有对称性,设双向链表结构具有对称性,设p指向双向链表中的某指向双向链表中的某一结点,则其对称性可用下式描述:一结点,则其对称性可用下式描述:(p-prior)-next=p=(p-next)-prior ; 结点结点p的存储位置存放在其的存储位置存放在其直接前趋结点直接前趋结点p-prior的的直接后继指针域直接后继指针域中,同时也存放在中,

103、同时也存放在其直接后继结点其直接后继结点p-next的的直接前趋指针域直接前趋指针域中。中。2 双向链表的基本操作双向链表的基本操作(1) 双向链表的插入双向链表的插入 将值为将值为e的结点插入双向链表中。的结点插入双向链表中。插入前后链表的变化如图插入前后链表的变化如图2-9所示。所示。Sepaiai+1Sepaiai+1图图2-9 双向链表的插入双向链表的插入岳醚婿粟逾驶教产额侦盛搁唤桐呸肺姨蹄勾钮撬俩丑账晶氦如昨淬寡坟捕数据结构严蔚敏PPT数据结构严蔚敏PPT 插入时仅仅指出直接前驱结点插入时仅仅指出直接前驱结点,钩链时必须注意,钩链时必须注意先后次序是先后次序是: “先右后左先右后左”

104、 。部分语句组如下:。部分语句组如下:S=(DulNode *)malloc(sizeof(DulNode); S-data=e;S-next=p-next; p-next-prior=S;p-next=S; S-prior=p; /* 钩链次序非常重要钩链次序非常重要 */ 插入时同时指出直接前驱结点插入时同时指出直接前驱结点p和直接后继结点和直接后继结点q,钩链时无须注意先后次序。部分语句组如下:,钩链时无须注意先后次序。部分语句组如下:S=(DulNode *)malloc(sizeof(DulNode);S-data=e;p-next=S; S-next=q;S-prior=p; q-

105、prior=S; 谋莉温帖呼赋黔似亢屯刊椰秒且证隐看泅娄塔窘五抨浸梆钓沿崖冀葵纬锥数据结构严蔚敏PPT数据结构严蔚敏PPT (2) 双向链表的结点删除双向链表的结点删除 设要删除设要删除的结点为的结点为p ,删除时可以不引入新的辅助,删除时可以不引入新的辅助指针变量,可以直接先断链,再释放结点。部分语句组指针变量,可以直接先断链,再释放结点。部分语句组如下:如下:p-prior-next=p-next;p-next-prior=p-prior;free(p);注意:注意: 与单链表的插入和删除操作不同的是,在双向链表与单链表的插入和删除操作不同的是,在双向链表中中插入插入和和删除删除必须同时必

106、须同时修改两个方向上的指针域的指向修改两个方向上的指针域的指向。倍心脐站晴旦慨氢仑默欲奠径劝叔汞家思蛀练灶姜骆职提谋梭涧尝翱烽绅数据结构严蔚敏PPT数据结构严蔚敏PPT2.5 一元多项式的表示和相加一元多项式的表示和相加1 一元多项式的表示一元多项式的表示 一元多项式一元多项式 p(x)=p0+p1x+p2x2+ +pnxn ,由,由n+1个个系数唯一确定系数唯一确定。则在计算机中可。则在计算机中可用线性表用线性表(p0 ,p1 ,p2 , ,pn )表示表示。既然是。既然是线性表线性表,就可以用顺序表和链,就可以用顺序表和链表来实现。两种不同实现方式的元素类型定义如下:表来实现。两种不同实现

107、方式的元素类型定义如下:(1) 顺序存储表示的类型顺序存储表示的类型typedef struct float coef; /*系数部分系数部分*/int expn; /*指数部分指数部分*/ ElemType ;(2) 链式存储表示的类型链式存储表示的类型typedef struct ploy float coef ; /*系数部分系数部分*/int expn ; /*指数部分指数部分*/struct ploy *next ; Ploy ;狞向良托豆辅丧杰荷慢功律钝跟肢伯段葡知颓帧吧屎沥嗣茬歼韧穆隧酬扭数据结构严蔚敏PPT数据结构严蔚敏PPT2 一元多项式的相加一元多项式的相加 不失一般性,设

108、有两个一元多项式不失一般性,设有两个一元多项式:P(x)=p0+p1x+p2x2+ +pnxn ,Q(x)=q0+q1x+q2x2+ +qmxm (mnext ; pb=Lb-next ;while (pa!=NULL&pb!=NULL) if (pa-expnexpn) pc-next=pa ; pc=pa ; pa=pa-next ; /* 将将pa所指的结点合并,所指的结点合并,pa指向下一个结点指向下一个结点 */if (pa-expnpb-expn) pc-next=pb ; pc=pb ; pb=pb-next ; /* 将将pb所指的结点合并,所指的结点合并,pb指向下一个结点指

109、向下一个结点 */舆坛败函政邯盯魂肠氖卵钱扮滁激八马扫过糯芍釜岭算上桥孜放仓饭萍音数据结构严蔚敏PPT数据结构严蔚敏PPTelse x=pa-coef+pb-coef ; if (abs(x)next ; free(ptr) ; ptr=pb ; pb=pb-next ; free(ptr) ; else /* 如果系数和不为如果系数和不为0,修改其中一个结,修改其中一个结点的系数域,删除另一个结点点的系数域,删除另一个结点 */ pc-next=pa ; pa-coef=x ; pc=pa ; pa=pa-next ; ptr=pb ; pb=pb-next ; free(pb) ; 阻闪看

110、努木硝枷潭裁届纶满确斑匣陕叹窜独既胀舆探匙寅凡榨聊洁彤肤嫉数据结构严蔚敏PPT数据结构严蔚敏PPT /* end of while */ if (pa=NULL) pc-next=pb ;else pc-next=pa ;return (Lc) ; 噬服咖插兵尹碗咕渡巷乘肋渝晃炔甫掇盎穿鸽犹耽诽稍燎珠澄荡靶崔县瘩数据结构严蔚敏PPT数据结构严蔚敏PPT算法之二:算法之二: 对两个多项式链表进行相加,生成一个新的相加后对两个多项式链表进行相加,生成一个新的相加后的结果多项式链表,原来两个多项式链表依然存在,的结果多项式链表,原来两个多项式链表依然存在,不发生任何改变,如果要再对原来两个多项式进行

111、其不发生任何改变,如果要再对原来两个多项式进行其它操作也不影响。它操作也不影响。屉楔消法埂周计氯崇背甘粥烹痕滓敖交记烧瓮隔农畔咱贬疲坯屎携啤套脆数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述Ploy *add_ploy(ploy *La, ploy *Lb) /* 将以将以La ,Lb为头指针表示的一元多项式相加,生成一个为头指针表示的一元多项式相加,生成一个新的结果多项式新的结果多项式 */ ploy *Lc , *pc , *pa , *pb , *p ; float x ;Lc=pc=(ploy *)malloc(sizeof(ploy) ; pa=La-next ; pb=L

112、b-next ;while (pa!=NULL&pb!=NULL) if (pa-expnexpn) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pa-coef ; p-expn=pa-expn ; p-next=NULL ; 宗唬肠嫌子捉郁丹榆羌座稳嗓俏扮屋向大敷劈裕秉绽绝把揣组塔芋喀陆姆数据结构严蔚敏PPT数据结构严蔚敏PPT /* 生成一个新的结果结点并赋值生成一个新的结果结点并赋值 */ pc-next=p ; pc=p ; pa=pa-next ; /* 生成的结点插入到结果链表的最后,生成的结点插入到结果链表的最后,pa指向下指向下一个结点一个结点

113、 */if (pa-expnpb-expn) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pb-expn ; p-next=NULL ; /* 生成一个新的结果结点并赋值生成一个新的结果结点并赋值 */ pc-next=p ; pc=p ; pb=pb-next ; /* 生成的结点插入到结果链表的最后,生成的结点插入到结果链表的最后,pb指指向下一个结点向下一个结点 */侠牛喂癣弛奎蛛录兽孪摄庶番捉梦觅撵汾辛舵霜茁龄豹廓宽绚醛苏艳谎炮数据结构严蔚敏PPT数据结构严蔚敏PPTif (pa-expn=pb-expn) x=pa-

114、coef+pb-coef ; if (abs(x)next ; pb=pb-next ; else /* 若系数和不为若系数和不为0,生成的结点插入到,生成的结点插入到结果链表的最后,结果链表的最后, pa, pb分别直接后继结点分别直接后继结点 */ p=(ploy *)malloc(sizeof(ploy) ; p-coef=x ; p-expn=pb-expn ; p-next=NULL ; /* 生成一个新的结果结点并赋值生成一个新的结果结点并赋值 */ pc-next=p ; pc=p ; pa=pa-next ; pb=pb-next ; 搓炉锐每缅幸秃磐臭阅赤翁珐辗男掳泼恨刽迷颧

115、吉辅酒泵桥券纳啊忠怨玄数据结构严蔚敏PPT数据结构严蔚敏PPT /* end of while */ if (pb!=NULL) while(pb!=NULL) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pb-expn ; p-next=NULL ; /* 生成一个新的结果结点并赋值生成一个新的结果结点并赋值 */ pc-next=p ; pc=p ; pb=pb-next ; 恨置棒钩棵希距公逃府炸迫扬筛喳闪箍阎逮慨蹬椎鞠怖勿心编膊秤疟过菏数据结构严蔚敏PPT数据结构严蔚敏PPTif (pa!=NULL) while(pa

116、!=NULL) p=(ploy *)malloc(sizeof(ploy) ; p-coef=pb-coef ; p-expn=pa-expn ; p-next=NULL ; /* 生成一个新的结果结点并赋值生成一个新的结果结点并赋值 */ pc-next=p ; pc=p ; pa=pa-next ; return (Lc) ; 褪希燕揍掸霸忱擦尉猫陡恢恨秘碌盈丛螟胎猫舀裹恃崇帽励貌幌荡尾非瑚数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 二二1 简述下列术语:线性表,顺序表,链表。简述下列术语:线性表,顺序表,链表。2 何时选用顺序表,何时选用链表作为线性表的存储何时选用顺序表,何时选

117、用链表作为线性表的存储结构合适结构合适?各自的主要优缺点是什么各自的主要优缺点是什么?3 在顺序表中插入和删除一个结点平均需要移动多少在顺序表中插入和删除一个结点平均需要移动多少个结点个结点?具体的移动次数取决于哪两个因素具体的移动次数取决于哪两个因素?4 链表所表示的元素是否有序链表所表示的元素是否有序?如有序,则有序性体如有序,则有序性体现于何处现于何处?链表所表示的元素是否一定要在物理上是相链表所表示的元素是否一定要在物理上是相邻的邻的?有序表的有序性又如何理解有序表的有序性又如何理解?5 设顺序表设顺序表L是递增有序表,试写一算法,将是递增有序表,试写一算法,将x插入插入到到L中并使中

118、并使L仍是递增有序表。仍是递增有序表。否劣熏射星辅熬枣棋醇宣树湖舷唤铀芯享痴月赔川殖蔑迹人见吹沸厚经裂数据结构严蔚敏PPT数据结构严蔚敏PPT6 写一求单链表的结点数目写一求单链表的结点数目ListLength(L)的算法。的算法。7 写一算法将单链表中值重复的结点删除写一算法将单链表中值重复的结点删除,使所得的,使所得的结果链表中所有结点的值均不相同。结果链表中所有结点的值均不相同。 8 写一算法从一给定的向量写一算法从一给定的向量A删除值在删除值在x到到y(xy)之间之间的所有元素的所有元素(注意:注意:x和和y是给定的参数,可以和表中的是给定的参数,可以和表中的元素相同,也可以不同元素相

119、同,也可以不同)。 9 设设A和和B是两个按元素值递增有序的单链表是两个按元素值递增有序的单链表,写一写一算法将算法将A和和B归并为按按元素值递减有序的单链表归并为按按元素值递减有序的单链表C,试,试分析算法的时间复杂度。分析算法的时间复杂度。拈横末伞戌潍炎吱涅犯耸雕缸蓉沪捌嘿浅针即沮稍羹聚挪角詹学绕鸣忙惕数据结构严蔚敏PPT数据结构严蔚敏PPT第第3章章 栈和队列栈和队列 栈和队列是两种应用非常广泛的数据结构栈和队列是两种应用非常广泛的数据结构,它们都,它们都来自线性表数据结构,来自线性表数据结构,都是都是“操作受限操作受限”的线性表的线性表。栈在计算机的实现有多种方式:栈在计算机的实现有多

120、种方式: 硬堆栈硬堆栈:利用:利用CPU中的某些寄存器组或类似的硬中的某些寄存器组或类似的硬件或使用内存的特殊区域来实现。这类堆栈容量有限,件或使用内存的特殊区域来实现。这类堆栈容量有限,但速度很快;但速度很快; 软堆栈软堆栈:这类堆栈主要在内存中实现。堆栈容量:这类堆栈主要在内存中实现。堆栈容量可以达到很大。在实现方式上,又有可以达到很大。在实现方式上,又有动态方式动态方式和和静态静态方式方式两种。两种。 本章将讨论栈和队列的基本概念本章将讨论栈和队列的基本概念、存储结构存储结构、基本基本操作以及这些操作的具体实现操作以及这些操作的具体实现。土腋卒点升缨胸纱庚豹藤搂涡怯寄途域旭惮入曹消艰海魏

121、拖摆帛与孟坟扛数据结构严蔚敏PPT数据结构严蔚敏PPT3.1 栈栈3.1.1 栈的基本概念栈的基本概念1 栈的概念栈的概念 栈栈(Stack):是限制在表的一端进行插入和删除操是限制在表的一端进行插入和删除操作的线性表。又称为后进先出作的线性表。又称为后进先出LIFO (Last In First Out)或先进后出或先进后出FILO (First In Last Out)线性线性表。表。 栈顶栈顶(Top):允许进行插入、删除操作的一端,又允许进行插入、删除操作的一端,又称为表尾。用栈顶指针称为表尾。用栈顶指针(top)来指示栈顶元素来指示栈顶元素。 栈底栈底(Bottom):是固定端,又称

122、为表头。是固定端,又称为表头。 空栈空栈:当表中没有元素时称为空栈。当表中没有元素时称为空栈。褐儿详波靖抱邢巍涸膝史蓟修至森忍褂替蔷果份佃讫狡疤管新洽呼淡袖炼数据结构严蔚敏PPT数据结构严蔚敏PPT 设栈设栈S=(a1,a2,an),则,则a1称称为栈底元素,为栈底元素,an为栈顶元素,如图为栈顶元素,如图3-1所示。所示。 栈中元素按栈中元素按a1,a2,an的次序的次序进栈,退栈的第一个元素应为栈顶元进栈,退栈的第一个元素应为栈顶元素。即栈的修改是按后进先出的原则素。即栈的修改是按后进先出的原则进行的。进行的。图图3-1 顺序顺序栈示意图栈示意图a1a2aianbottomtop进栈(进栈

123、(push)出栈出栈(pop)2 栈的抽象数据类型定义栈的抽象数据类型定义ADT Stack数据对象:数据对象:D = ai|aiElemSet, i=1,2,n,n0 数据关系:数据关系:R =|ai-1,aiD, i=2,3,n 基本操作:初始化、进栈、出栈、取栈顶元素等基本操作:初始化、进栈、出栈、取栈顶元素等 ADT Stack韶鸦希砾碱选丛填贾奖育属蔗免帆低铬待鼎叁苯箭呢糟毒蟹抗睫争僵其纬数据结构严蔚敏PPT数据结构严蔚敏PPT 栈的顺序存储结构简称为顺序栈,和线性表相类似,栈的顺序存储结构简称为顺序栈,和线性表相类似,用用一维数组一维数组来来存储栈存储栈。根据数组是否可以根据需要增

124、大,。根据数组是否可以根据需要增大,又可分为又可分为静态顺序栈静态顺序栈和和动态顺序栈动态顺序栈。 静态顺序栈静态顺序栈实现简单,但不能根据需要增大栈的实现简单,但不能根据需要增大栈的存储空间;存储空间; 动态顺序栈动态顺序栈可以根据需要增大栈的存储空间,但可以根据需要增大栈的存储空间,但实现稍为复杂。实现稍为复杂。3.1.2 栈的顺序存储表示栈的顺序存储表示誓写伶使至蒂枢苛祥膨祸锄仆捕萄量努辑香簧试互存追掐缄肤娱获甥松剖数据结构严蔚敏PPT数据结构严蔚敏PPT 采用采用动态动态一维数组一维数组来来存储栈存储栈。所谓动态,指的是栈。所谓动态,指的是栈的大小可以根据需要增加。的大小可以根据需要增

125、加。 用用bottom表示栈底指针,栈底固定不变的;栈顶表示栈底指针,栈底固定不变的;栈顶则随着进栈和退栈操作而变化。用则随着进栈和退栈操作而变化。用top( (称为栈顶指针称为栈顶指针) )指示当前栈顶位置。指示当前栈顶位置。 用用top=bottom作为栈空的标记作为栈空的标记,每次,每次top指向栈顶指向栈顶数组中的下一个存储位置数组中的下一个存储位置。 结点进栈结点进栈:首先将数据元素保存到栈顶首先将数据元素保存到栈顶(top所所指的当前位置指的当前位置),然后执行,然后执行top加加1,使,使top指向栈顶的指向栈顶的下一个存储位置下一个存储位置;3.1.2.1 栈的动态顺序存储表示

126、栈的动态顺序存储表示皂灿竟僻锚哥趣杨秒输忿缔乖养簿蔚纂稻耸蛹粮哗睡倒表敏物垢饲柬累氨数据结构严蔚敏PPT数据结构严蔚敏PPT 结点出栈结点出栈:首先执行首先执行top减减1,使,使top指向栈顶元指向栈顶元素的存储位置,然后将栈顶元素取出素的存储位置,然后将栈顶元素取出。 图图3-2是一个动态栈的变化示意图是一个动态栈的变化示意图。图图3-2 (动态动态)堆栈变化示意图堆栈变化示意图空栈空栈bottomtop元素元素a进栈进栈bottomtopa元素元素b,c进栈进栈bottomtopabc元素元素c退栈退栈bottomtopabbottomtopabdef元素元素d,e,f进栈进栈浸坞友单阅

127、机兢吱雷愿羊炉酋珊胆翼公歪柯垦噬酌平臆练鲤惕轿刨庚芋灶数据结构严蔚敏PPT数据结构严蔚敏PPT基本操作的实现基本操作的实现1 栈的类型定义栈的类型定义#define STACK_SIZE 100 /* 栈初始向量大小栈初始向量大小 */#define STACKINCREMENT 10 /* 存储空间分配增量存储空间分配增量 */#typedef int ElemType ;typedef struct sqstack ElemType *bottom; /* 栈不存在时值为栈不存在时值为NULL */ElemType *top; /* 栈顶指针栈顶指针 */int stacksize ; /

128、* 当前已分配空间,以元素为单位当前已分配空间,以元素为单位 */SqStack ;耐坦患衰菲乔莹然炳阳剩澄喂鹅蹬呻陌莹勤疆泼煽辐人昨拄保锻康茫刁禹数据结构严蔚敏PPT数据结构严蔚敏PPT2 栈的初始化栈的初始化Status Init_Stack(void) SqStack S ;S.bottom=(ElemType *)malloc(STACK_SIZE *sizeof(ElemType);if (! S.bottom) return ERROR;S.top=S.bottom ; /* 栈空时栈顶和栈底指针相同栈空时栈顶和栈底指针相同 */S. stacksize=STACK_SIZE; r

129、eturn OK ;坞愉费巳殊浇胯硷殊卸伶拖捌四淳班嘛婆濒和褂沽损驰赃臼尺浚逼屉薪剂数据结构严蔚敏PPT数据结构严蔚敏PPT3 压栈压栈(元素进栈元素进栈)Status push(SqStack S , ElemType e) if (S.top-S.bottom=S. stacksize-1) S.bottom=(ElemType *)realloc(S. STACKINCREMENT+STACK_SIZE) *sizeof(ElemType); /* 栈满,追加存储空间栈满,追加存储空间 */if (! S.bottom) return ERROR; S.top=S.bottom+S. s

130、tacksize ;S. stacksize+=STACKINCREMENT ; *S.top=e; S.top+ ; /* /* 栈顶指针加栈顶指针加1,e成为新的栈顶成为新的栈顶 */ */return OK;宿言拂祥量尊们习绩率照请乱睫诽束辊丧霸笼淤扮宋跑怯面羊拉播尺黔屈数据结构严蔚敏PPT数据结构严蔚敏PPT4 弹栈弹栈( (元素元素出栈出栈) )Status pop( SqStack S, ElemType *e ) /*弹出栈顶元素弹出栈顶元素*/ if ( S.top= S.bottom ) return ERROR ; /* 栈空,返回失败标志栈空,返回失败标志 */S.top

131、- ; e=*S. top ; return OK ; 失寿午堕晌评起袋奏草昨趁眯做妈犁保弛养茵夸沉姬谴斋黍厨卒旨锤纬减数据结构严蔚敏PPT数据结构严蔚敏PPT 采用采用静态静态一维数组一维数组来来存储栈存储栈。 栈底固定不变的,而栈顶则随着进栈和退栈操作变栈底固定不变的,而栈顶则随着进栈和退栈操作变化的,化的, 栈底固定不变的;栈顶则随着进栈和退栈操作而栈底固定不变的;栈顶则随着进栈和退栈操作而变化,用一个整型变量变化,用一个整型变量top( (称为栈顶指针称为栈顶指针) )来指示当前来指示当前栈顶位置。栈顶位置。 用用top=0表示栈空的初始状态表示栈空的初始状态,每次,每次top指向栈顶

132、指向栈顶在数组中的存储位置在数组中的存储位置。 结点进栈结点进栈:首先执行首先执行top加加1,使,使top指向新的栈指向新的栈顶位置顶位置,然后将数据元素保存到栈顶然后将数据元素保存到栈顶(top所指的当前所指的当前位置位置)。3.1.2.2 栈的静态顺序存储表示栈的静态顺序存储表示察家涡掸汛汗戌踩噪傲吃施本捎雄巢莱恍桅辽字斌叔盏光近尔幸档盟屹旱数据结构严蔚敏PPT数据结构严蔚敏PPT 结点出栈结点出栈:首先首先把把top指向的栈顶元素取出指向的栈顶元素取出,然然后执行后执行top减减1,使,使top指向新的栈顶位置指向新的栈顶位置。 若栈的数组有若栈的数组有Maxsize个元素个元素,则,

133、则top=Maxsize-1时时栈满栈满。图。图3-3是一个大小为是一个大小为5的栈的变化示意图的栈的变化示意图。图图3-3 静态静态堆栈变化示意图堆栈变化示意图空栈空栈bottomtopTop=11个元素进栈个元素进栈bottomtopaTop=33个元素进栈个元素进栈bottomtopabcTop=4栈满栈满bottomtopabedTop=2元素元素c进栈进栈bottomtopab揣亿抡蜀举疚碾澜救棘滑笆跨驹泣颇巾乌铱梧蓖茸瓤傲喜呈划轧踩镐番慌数据结构严蔚敏PPT数据结构严蔚敏PPT基本操作的实现基本操作的实现1 栈的类型定义栈的类型定义# define MAX_STACK_SIZE 1

134、00 /* 栈向量大小栈向量大小 */# typedef int ElemType ;typedef struct sqstack ElemType stack_arrayMAX_STACK_SIZE ;int top;SqStack ;饼碘表隶受愁氖薛停团蝇吵娱扑搐闽范袍房箭韦限勃泌前庄觉明御细狐折数据结构严蔚敏PPT数据结构严蔚敏PPT2 栈的初始化栈的初始化SqStack Init_Stack(void) SqStack S ;S.bottom=S.top=0 ; return(S) ;当苫拥悠惕神绞奠基淫笨呕蛙透纽完朝捏鲁堂回纶痕鞘晓志础琼闪藕密逸数据结构严蔚敏PPT数据结构严蔚敏PP

135、T3 压栈压栈(元素进栈元素进栈)Status push(SqStack S , ElemType e) /* /* 使数据元素使数据元素e进栈成为新的栈顶进栈成为新的栈顶 */ */ if (S.top=MAX_STACK_SIZE-1) return ERROR; /* 栈满,返回错误标志栈满,返回错误标志 */S.top+ ; /* /* 栈顶指针加栈顶指针加1 */*/S.stack_arrayS.top=e ; /* /* e成为新的栈顶成为新的栈顶 */ */return OK; /* 压栈成功压栈成功 */别尾院姜感侍银矮布掠辞拴柒公伤愚添侨遗难蜀池浆浙绞覆防炮多榷倍麻数据结构严

136、蔚敏PPT数据结构严蔚敏PPT4 弹栈弹栈( (元素元素出栈出栈) )Status pop( SqStack S, ElemType *e ) /*弹出栈顶元素弹出栈顶元素*/ if ( S.top=0 )return ERROR ; /* 栈空,返回错误标志栈空,返回错误标志 */*e=S.stack_arrayS.top ; S.top- ; return OK ; 取挺劫恨硒痈绩退斡洗光履狐贡辖萌靠掷倔惧氛栏良哗寨孪鹿砒琶厦鲸油数据结构严蔚敏PPT数据结构严蔚敏PPT 当栈满时做进栈运算必定产生空间溢出,简称当栈满时做进栈运算必定产生空间溢出,简称“上上溢溢”。上溢是一种出错状态,应设法

137、避免。上溢是一种出错状态,应设法避免。 当栈空时做退栈运算也将产生溢出,简称当栈空时做退栈运算也将产生溢出,简称“下溢下溢”。下溢则可能是正常现象,因为栈在使用时,其初态或终下溢则可能是正常现象,因为栈在使用时,其初态或终态都是空栈,所以下溢常用来作为控制转移的条件。态都是空栈,所以下溢常用来作为控制转移的条件。撂隐慈丑顶班憾拯睡管瑶之膝稀楚精塌旋良孜藏记柜示令舜迅墒娩甫权媳数据结构严蔚敏PPT数据结构严蔚敏PPT1 栈的链式表示栈的链式表示 栈的栈的链式存储结构链式存储结构称为链栈,是运算受限的单链表。称为链栈,是运算受限的单链表。其插入和删除操作只能在表头位置上进行。因此,链栈其插入和删除

138、操作只能在表头位置上进行。因此,链栈没有必要像单链表那样附加头结点,栈顶指针没有必要像单链表那样附加头结点,栈顶指针top就是就是链表的头指针。图链表的头指针。图3-4是栈的链式存储表示形式是栈的链式存储表示形式。3.1.3 栈的链式存储表示栈的链式存储表示空栈空栈top 非空栈非空栈top a4 a3 a1 a2图图图图3-4 3-4 链链链链栈存储形式栈存储形式链栈的链栈的结点类型说明如下:结点类型说明如下:typedef struct Stack_Node ElemType data ;struct Stack_Node *next ; Stack_Node ;述捉历排跺品苏曾课乒急簧悸

139、缅橱育协屠依油痪豹似硒泻虱囊有烧哀蚂桓数据结构严蔚敏PPT数据结构严蔚敏PPT2 链栈基本操作的实现链栈基本操作的实现(1) 栈的初始化栈的初始化Stack_Node *Init_Link_Stack(void) Stack_Node *top ;top=(Stack_Node *)malloc(sizeof(Stack_Node ) ;top-next=NULL ; return(top) ;沿猎阎肠醛筑挡西窃皂硅潞憾碳筋跋瓣憨值捶汾湃启臼些瞒游皑窗毁译完数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 压栈压栈(元素进栈元素进栈)Status push(Stack_Node *top , E

140、lemType e) Stack_Node *p ;p=(Stack_Node *)malloc(sizeof(Stack_Node) ; if (!p) return ERROR; /* 申请新结点失败,返回错误标志申请新结点失败,返回错误标志 */p-data=e ; p-next=top-next ; top-next=p ; /* 钩链钩链 */return OK;惩桌者帜拎溶弗棠夜梅京纫媳蛛招酒予僵浴漠旦麓颐咬脉挖嘉痢宜晴睡六数据结构严蔚敏PPT数据结构严蔚敏PPT(3) 弹栈弹栈( (元素元素出栈出栈) )Status pop(Stack_Node *top , ElemType

141、*e)/* /* 将栈顶元素将栈顶元素出出栈栈 */ */ Stack_Node *p ;ElemType e ;if (top-next=NULL )return ERROR ; /* 栈空,返回错误标志栈空,返回错误标志 */p=top-next ; e=p-data ; /* /* 取栈顶元素取栈顶元素 */ */top-next=p-next ; /* /* 修改栈顶指针修改栈顶指针 */ */free(p) ; return OK ;嫉瓮腾买土垂惹是荐剑午称娇顾篱曼室虞扰金榴欲景克媳陵星墩盗蹬竣聋数据结构严蔚敏PPT数据结构严蔚敏PPT3.2 栈的应用栈的应用 由于栈具有的由于栈具有

142、的“后进先出后进先出”的固有特性,因此,栈的固有特性,因此,栈成为程序设计中常用的工具和数据结构。以下是几个栈成为程序设计中常用的工具和数据结构。以下是几个栈应用的例子。应用的例子。迎权模哮葡泅迎卑针史竭陡纠暮果律丽扯凭甄啃箍泄塔箭仑酱鹊桌滩难速数据结构严蔚敏PPT数据结构严蔚敏PPT3.2.1 数制转换数制转换 十进制整数十进制整数N向其它进制数向其它进制数d(二二、八八、十六十六) )的转换的转换是计算机实现计算的基本问题。是计算机实现计算的基本问题。转换法则转换法则:该转换法则对应于一个简单算法原理该转换法则对应于一个简单算法原理: :n=(n div d)*d+n mod d 其中:其

143、中:div为整除运算为整除运算, ,mod为求余运算为求余运算例如例如 (1348)10= (2504)8,其运算过程如下:其运算过程如下: n n div 8 n mod 8 1348 168 4 168 21 0 21 2 5 2 0 2卑名搽芹吟绎溜廓恃趾尿炒获捍擎跪熊贿毋昭匡腿疥袭折拧魄嘲臣顺排鲍数据结构严蔚敏PPT数据结构严蔚敏PPT 采用静态顺序栈方式实现采用静态顺序栈方式实现 void conversion(int n , int d) /*将将十进制整数十进制整数N转换为转换为d(2或或8)进制数进制数*/ SqStack S ; int k, *e ;S=Init_Stack

144、();while (n0) k=n%d ; push(S , k) ; n=n/d ; /* 求出所有的余求出所有的余数,数,进栈进栈 */while (S.top!=0) /* 栈不空时出栈,输出栈不空时出栈,输出 */ pop(S, e) ; printf(“%1d” , *e) ; 塔办畦靳粕舆颠倚搏畸阜磺努翘辩帧馅土吸前蛔镰派叭帘凳川运粟荷敷灶数据结构严蔚敏PPT数据结构严蔚敏PPT3.2.2 括号匹配问题括号匹配问题 在文字处理软件或编译程序设计时,常常需要检查在文字处理软件或编译程序设计时,常常需要检查一个字符串或一个表达式中的括号是否相匹配一个字符串或一个表达式中的括号是否相匹配

145、?匹配思想匹配思想:从左至右扫描一个字符串从左至右扫描一个字符串(或表达式或表达式),则,则每个右括号将与最近遇到的那个左括号相匹配每个右括号将与最近遇到的那个左括号相匹配。则可以。则可以在从左至右扫描过程中把所遇到的左括号存放到堆栈中。在从左至右扫描过程中把所遇到的左括号存放到堆栈中。每当遇到一个右括号时,就将它与栈顶的左括号每当遇到一个右括号时,就将它与栈顶的左括号(如果如果存在存在)相匹配,同时从栈顶删除该左括号。相匹配,同时从栈顶删除该左括号。算法思想算法思想:设置一个栈,当读到左括号时,左括号进设置一个栈,当读到左括号时,左括号进栈。当读到右括号时,则从栈中弹出一个元素,与读到栈。当

146、读到右括号时,则从栈中弹出一个元素,与读到的左括号进行匹配,若匹配成功,继续读入;否则匹配的左括号进行匹配,若匹配成功,继续读入;否则匹配失败,返回失败,返回FLASE。麦右匝桐墨塑习营嘲瘪扔鱼碳莎摊着授兽畔明沥浴亢捎桶舰薛各庄熊易柯数据结构严蔚敏PPT数据结构严蔚敏PPT算法描述算法描述#define TRUE 0#define FLASE -1SqStack S ; S=Init_Stack() ; /*堆栈初始化堆栈初始化*/int Match_Brackets( ) char ch , x ;scanf(“%c” , &ch) ; while (asc(ch)!=13)春植枚瀑尸雷若际

147、色烙悬欺犁誓蓑豺收迎继毙孺戒绍缉颐足娥暖汤湘票造数据结构严蔚敏PPT数据结构严蔚敏PPT if (ch=()|(ch=) push(S , ch) ; else if (ch=) x=pop(S) ; if (x!=) printf(“括号不匹配括号不匹配”) ; return FLASE ; else if (ch=) x=pop(S) ; if (x!=() printf(“(括号不匹配括号不匹配”) ; return FLASE ; 苍驭安当馋炸锐族林目咏天板笼私稚言施谈赤轨烁运硼劲积守砧熏被萎蔫数据结构严蔚敏PPT数据结构严蔚敏PPTif (S.top!=0) printf(“括号数量

148、不匹配!括号数量不匹配!”) ; return FLASE ;else return TRUE ; 窒酣肤泊民厂人又纷冗胞细弱关鸽冤槛蝗杆释蜘渺尿蹬固潮酿牺獭陆商邹数据结构严蔚敏PPT数据结构严蔚敏PPT3.2.2 栈与递归调用的实现栈与递归调用的实现 栈的另一个重要应用是在程序设计语言中实现递归栈的另一个重要应用是在程序设计语言中实现递归调用。调用。 递归调用递归调用:一个函数一个函数( (或过程或过程) )直接或间接地调用直接或间接地调用自己本身,简称自己本身,简称递归递归(Recursive)。 递归递归是程序设计中的一个强有力的工具。因为递归是程序设计中的一个强有力的工具。因为递归函数

149、结构清晰,程序易读,正确性很容易得到证明。函数结构清晰,程序易读,正确性很容易得到证明。 为了使递归调用不至于无终止地进行下去,实际上为了使递归调用不至于无终止地进行下去,实际上有效的递归调用函数有效的递归调用函数( (或过程或过程) )应包括两部分:应包括两部分:递推规则递推规则( (方法方法) ),终止条件终止条件。例如:求例如:求n!正毋短炬辕眺曼顽务剧替铺都坛桌盐踌已瓷归沉好殿沛轰抨捶撞澜膨伪椭数据结构严蔚敏PPT数据结构严蔚敏PPTFact(n)=1 当当n=0时时 终止条件终止条件n*fact(n-1) 当当n0时时 递推规则递推规则 为保证递归调用正确执行,系统设立一个为保证递归

150、调用正确执行,系统设立一个“递归工递归工作栈作栈”,作为整个递归调用过程期间使用的数据存储区。,作为整个递归调用过程期间使用的数据存储区。 每一层递归包含的信息如:每一层递归包含的信息如:参数参数、局部变量局部变量、上一上一层的返回地址构成层的返回地址构成一个一个“工作记录工作记录” 。每进入一层递归,。每进入一层递归,就产生一个新的工作记录压入栈顶;每退出一层递归,就产生一个新的工作记录压入栈顶;每退出一层递归,就从栈顶弹出一个工作记录。就从栈顶弹出一个工作记录。降修炊煽勺事么祭嘻蘸肖抉羞踌勇镑轻摈绑嗓驳队擒檀撞挫雇渭邀阉叼梁数据结构严蔚敏PPT数据结构严蔚敏PPT 从被调函数返回调用函数的

151、一般步骤:从被调函数返回调用函数的一般步骤:(1) 若栈为空,则执行正常返回。若栈为空,则执行正常返回。 从栈顶弹出一个工作记录。从栈顶弹出一个工作记录。 将将“工作记录工作记录”中的参数值、局部变量值赋给相中的参数值、局部变量值赋给相应的变量;读取返回地址。应的变量;读取返回地址。 将函数值赋给相应的变量。将函数值赋给相应的变量。(5) 转移到返回地址。转移到返回地址。奇坞镀襟锦肛羽翰蒸锈勾爽甄长北缘象逐峪弊曳铝喊馈宿姆卞甭曹胰冀寻数据结构严蔚敏PPT数据结构严蔚敏PPT1 队列的基本概念队列的基本概念 队列队列(Queue):也是运算受限的线性表。是一种:也是运算受限的线性表。是一种先先进

152、先出进先出(First In First Out ,简称,简称FIFO)的线性表。只的线性表。只允许在表的一端进行插入,而在另一端进行删除。允许在表的一端进行插入,而在另一端进行删除。 队首队首(front) :允许进行删除的一端称为队首。:允许进行删除的一端称为队首。 队尾队尾(rear) :允许进行插入的一端称为队尾。:允许进行插入的一端称为队尾。例如:排队购物。操作系统中的作业排队。先进入例如:排队购物。操作系统中的作业排队。先进入队列的成员总是先离开队列。队列的成员总是先离开队列。3.3 队队 列列3.3.1 队列及其基本概念队列及其基本概念坐小由饥腋选屠诣建侥枢乏掩戏糙赫拷炯酒垂拘筷

153、婴蠕溪掣痔慕湘豆骚址数据结构严蔚敏PPT数据结构严蔚敏PPT 队列中没有元素时称为空队列。在空队列中依次队列中没有元素时称为空队列。在空队列中依次加入元素加入元素a1, a2, , an之后,之后,a1是队首元素,是队首元素,an是队尾是队尾元素。显然退出队列的次序也只能是元素。显然退出队列的次序也只能是a1, a2, , an ,即队列的修改是依即队列的修改是依先进先出先进先出的原则进行的,如图的原则进行的,如图3-5所所示。示。a1 , a2 , , an出队出队入队入队队尾队尾队首队首图图3-5 队列示意图队列示意图2 队列的抽象数据类型定义队列的抽象数据类型定义ADT Queue数据对

154、象:数据对象:D = ai|aiElemSet, i=1, 2, , n, n = 0 缀仁子历吱悲蝗缝专蔓拧萨夕泌柜苫飘腺帘偷谁惑谅懊坡涸叁烃肃慎搽泰数据结构严蔚敏PPT数据结构严蔚敏PPT数据关系:数据关系:R = | ai-1, aiD, i=2,3,n 约定约定a1端为队首,端为队首,an端为队尾。端为队尾。基本操作:基本操作:Create():创建一个空队列:创建一个空队列;EmptyQue():若队列为空:若队列为空,则返回则返回true ,否则返否则返回回flase ;InsertQue(x) :向队尾插入元素:向队尾插入元素x;DeleteQue(x) :删除队首元素:删除队首

155、元素x; ADT Queue伶券芍绢礁浩体檬杯豺签苏岭砧彭饿莱菱务威兹嘎徒基烦峪宛穆播甜邵灰数据结构严蔚敏PPT数据结构严蔚敏PPT3.3.2 队列的顺序表示和实现队列的顺序表示和实现 利用利用一组连续的存储单元一组连续的存储单元(一维数组一维数组) 依次存放从队依次存放从队首到队尾的各个元素,称为首到队尾的各个元素,称为顺序队列顺序队列。 对于队列,和顺序栈相类似,也有动态和静态之分。对于队列,和顺序栈相类似,也有动态和静态之分。本部分介绍的是本部分介绍的是静态顺序队列静态顺序队列,其类型定义如下:,其类型定义如下:#define MAX_QUEUE_SIZE 100typedef stru

156、ct queue ElemType Queue_arrayMAX_QUEUE_SIZE ;int front ;int rear ;SqQueue;陈孜茧瞬喀盈涌协凝评盏吨帅摄吊矫掂耗艰膳拟培至缅关竭丙求啡蟹洱毕数据结构严蔚敏PPT数据结构严蔚敏PPT3.3.2.1 队列的顺序队列的顺序存储结构存储结构 设立一个设立一个队首指针队首指针front ,一个,一个队尾指针队尾指针rear ,分,分别指向队首和队尾元素别指向队首和队尾元素。 初始化初始化:front=rear=0。 入队入队:将新元素插入将新元素插入rear所指的位置,然后所指的位置,然后rear加加1。 出队出队:删去删去fron

157、t所指的元素,然后加所指的元素,然后加1并返回被删并返回被删元素。元素。 队列为空队列为空:front=rear。 队满队满:rear=MAX_QUEUE_SIZE-1或或front=rear。萄按彩戌讲卸氏攘泅迷凄讲撑扶涨挂圣炙胶赎县今得糕刑筛奈榨奉颠忽续数据结构严蔚敏PPT数据结构严蔚敏PPT 在非空队列里,队首指针始终指向队头元素,而队在非空队列里,队首指针始终指向队头元素,而队尾指针始终指向队尾元素的下一位置。尾指针始终指向队尾元素的下一位置。 顺序队列中存在顺序队列中存在“假溢出假溢出”现象。因为在入队和出现象。因为在入队和出队操作中,头、尾指针只增加不减小,致使被删除元素队操作中,

158、头、尾指针只增加不减小,致使被删除元素的空间永远无法重新利用。因此,尽管队列中实际元素的空间永远无法重新利用。因此,尽管队列中实际元素个数可能远远小于数组大小,但可能由于尾指针巳超出个数可能远远小于数组大小,但可能由于尾指针巳超出向量空间的上界而不能做入队操作。该现象称为向量空间的上界而不能做入队操作。该现象称为假溢出假溢出。如图如图3-6所示是数组大小为所示是数组大小为5的顺序队列中队首的顺序队列中队首、队尾指队尾指针和队列中元素的变化情况。针和队列中元素的变化情况。旨欺暖熬光吸酵便废澄锡北傣貉怠朋掀语凶遁吕办帖蹄稳描锌洱号嫩酉斗数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 空队列空队列Q

159、.frontQ.rear(b)入队入队3个元素个元素a3a2a1Q.frontQ.rear(c) 出队出队3个元素个元素Q.frontQ.rear(d) 入队入队2个元素个元素a5a4Q.frontQ.rear图图3-6 队列示意图队列示意图鄂辐谴在剿鄙侄炉冈弯拈蔡滚魄苍晰惰身伍抵尿谅绘哎章懒嗡唐彦锑上抨数据结构严蔚敏PPT数据结构严蔚敏PPT3.3.2.2 循环队列循环队列 为充分利用向量空间,克服上述为充分利用向量空间,克服上述“假溢出假溢出”现象的现象的方法是:将为队列分配的方法是:将为队列分配的向量空间看成为一个首尾相接向量空间看成为一个首尾相接的圆环的圆环,并称这种队列为,并称这种队

160、列为循环队列循环队列(Circular Queue)。 在循环队列中进行出队、入队操作时,队首、队尾在循环队列中进行出队、入队操作时,队首、队尾指针仍要加指针仍要加1,朝前移动。只不过当队首、队尾指针指,朝前移动。只不过当队首、队尾指针指向向量上界向向量上界(MAX_QUEUE_SIZE-1)时,其加时,其加1操作的结果操作的结果是指向向量的下界是指向向量的下界0。这种循环意义下的加这种循环意义下的加1操作可以描述为:操作可以描述为:if (i+1=MAX_QUEUE_SIZE) i=0;else i+ ;其中:其中: i代表队首指针代表队首指针(front)或队尾指针或队尾指针(rear)抬

161、捍禽可辣忿戒断右娩雌枫倍驻菜眨睫识秒粱筑兆害搏拼汐邦始艺赌柿钧数据结构严蔚敏PPT数据结构严蔚敏PPT用模运算可简化为:用模运算可简化为:i=(i+1)%MAX_QUEUE_SIZE ; 显然,为循环队列所分配的空间可以被充分利用,显然,为循环队列所分配的空间可以被充分利用,除非向量空间真的被队列元素全部占用,否则不会上溢。除非向量空间真的被队列元素全部占用,否则不会上溢。因此,真正实用的顺序队列是循环队列。因此,真正实用的顺序队列是循环队列。 例:设例:设有循环队列有循环队列QU0,5,其初始状态是,其初始状态是front=rear=0,各种操作后队列的头、尾指针的状态变,各种操作后队列的头

162、、尾指针的状态变化情况如下图化情况如下图3-7所示。所示。 123450(a) 空队列空队列frontrear123450(b) d, e, b, g入入队队frontdebgrear123450(c) d, e出队出队bgfrontrear贡洁铲蔼炒苇泌慢扼抿隧靶桌诀骚熔甥建推槽粪膘惨泄床戈椅皇殿算仟隆数据结构严蔚敏PPT数据结构严蔚敏PPT 入队时尾指针向前追赶头指针,出队时头指针向前入队时尾指针向前追赶头指针,出队时头指针向前追赶尾指针,故队空和队满时头尾指针均相等。因此,追赶尾指针,故队空和队满时头尾指针均相等。因此,无法通过无法通过front=rear来判断队列来判断队列“空空”还是

163、还是“满满”。解。解决此问题的方法是:约定入队前,测试尾指针在循环意决此问题的方法是:约定入队前,测试尾指针在循环意义下加义下加1后是否等于头指针,若相等则认为队满后是否等于头指针,若相等则认为队满。即。即: rear所指的单元始终为空。所指的单元始终为空。123450(d) i, j, k入入队队bgfrontijkrear123450(e) b, g出队出队ijkrearfront123450(f) r, p, s, t入队入队ijkfrontrprear图图3-7 循环队列操作及指针变化情况循环队列操作及指针变化情况黔醚幻鸿旭省系镣弄兴绎委术睁塘豹福给苯租仗症谢束康段唬舵坷涯亮蓖数据结构

164、严蔚敏PPT数据结构严蔚敏PPT 循环队列为空循环队列为空:front=rear 。 循环队列满循环队列满:(rear+1)%MAX_QUEUE_SIZE =front。循环队列的基本操作循环队列的基本操作1 循环队列的初始化循环队列的初始化SqQueue Init_CirQueue(void) SqQueue Q ;Q.front=Q.rear=0; return(Q) ;兄戌淄练揣呐益脚埂南吩斜椅柒沦甲老父闽蒸哮镜蔫逸八瞪言还污友斟涎数据结构严蔚敏PPT数据结构严蔚敏PPT2 入队操作入队操作Status Insert_CirQueue(SqQueue Q , ElemType e) /*

165、 /* 将数据元素将数据元素e插入到循环队列插入到循环队列Q的队尾的队尾 */ */ if (Q.rear+1)%MAX_QUEUE_SIZE= Q.front)return ERROR; /* 队满,返回错误标志队满,返回错误标志 */Q.Queue_arrayQ.rear=e ; /* /* 元素元素e入队入队 */ */Q.rear=(Q.rear+1)% MAX_QUEUE_SIZE ; /* 队尾指针向前移动队尾指针向前移动 */return OK; /* 入队成功入队成功 */硒酌农钥曹谈坟双洒烃麦悟根民比咋雕轮衔傣蓬境绚潮臻樱标掺帆焚去惠数据结构严蔚敏PPT数据结构严蔚敏PPT3

166、 出队操作出队操作Status Delete_CirQueue(SqQueue Q, ElemType *x ) /* /* 将循环队列将循环队列Q的队首元素出队的队首元素出队 */ */ if (Q.front+1= Q.rear)return ERROR ; /* 队空,返回错误标志队空,返回错误标志 */*x=Q.Queue_arrayQ.front ; /* /* 取队首元素取队首元素 */ */Q.front=(Q.front+1)% MAX_QUEUE_SIZE ; /* 队首指针向前移动队首指针向前移动 */return OK ;宿纯但辑须萝恼北医院碰泵险苦夹枷配谋砧憋凌阜缴扣场

167、徒怠搓涉闹梯呀数据结构严蔚敏PPT数据结构严蔚敏PPT1 队列的链式存储表示队列的链式存储表示 队列的链式存储结构简称为链队列,它是限制仅队列的链式存储结构简称为链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。在表头进行删除操作和表尾进行插入操作的单链表。 需要两类不同的结点需要两类不同的结点:数据元素数据元素结点结点,队列的队列的队首队首指针和队尾指针指针和队尾指针的结点的结点,如图,如图3-8所示。所示。3.3.3 队列的链式表示和实现队列的链式表示和实现数据元素结点类型定义:数据元素结点类型定义:typedef struct Qnode ElemType data ;st

168、ruct Qnode *next ;QNode ;数据元素结点数据元素结点data指针结点指针结点front rear图图3-8 链队列结点示意图链队列结点示意图名畴柴躬酣谚穗泵疯羌巍居蠕挪雇挫睁文截贫屋宝妨仇摊葵惨盼仍防鸡谊数据结构严蔚敏PPT数据结构严蔚敏PPT指针结点类型定义:指针结点类型定义:typedef struct link_queue QNode *front , *rear ;Link_Queue ;2 链队运算及指针变化链队运算及指针变化 链队的操作实际上是单链表的操作,只不过是删链队的操作实际上是单链表的操作,只不过是删除在表头进行,插入在表尾进行。插入、删除时分别修除在

169、表头进行,插入在表尾进行。插入、删除时分别修改不同的指针。链队运算及指针变化如图改不同的指针。链队运算及指针变化如图3-9所示。所示。郑嘘边柏访努旨竟赦漏朝颓净戊婪遭瞎疮啪啸惦吾灼木拂腾情天磺犁拥氟数据结构严蔚敏PPT数据结构严蔚敏PPT图图3-9 队列操作及指针变化队列操作及指针变化(a) 空队列空队列front rear(b) x入队入队 x front rear(c) y再入队再入队 y front rear x(d) x出队出队 y xfront rear溜姐反途尤旨喀历翁任啪储平耀驭饿软拱稠待放贪星蓝咨浊肉拉叹掉桔李数据结构严蔚敏PPT数据结构严蔚敏PPT3 链队列的基本操作链队列的

170、基本操作 链队列的初始化链队列的初始化LinkQueue *Init_LinkQueue(void) LinkQueue *Q ; QNode *p ;p=(QNode *)malloc(sizeof(QNode) ; /* 开辟头结开辟头结点点 */p-next=NULL ;Q=(LinkQueue *)malloc(sizeof(LinkQueue) ; /* 开辟链队的指针结点开辟链队的指针结点 */Q.front=Q.rear=p ; return(Q) ;氦首懈淫桔化蛆府虞此插槛阔陵识首尊娱惋犁圈除拦抨础扳您卧顽垛效韩数据结构严蔚敏PPT数据结构严蔚敏PPT 链队列的链队列的入队操作

171、入队操作 在已知队列的队尾插入一个元素在已知队列的队尾插入一个元素e ,即,即修改队尾修改队尾指针指针(Q.rear)。Status Insert_CirQueue(LinkQueue *Q , ElemType e) /* /* 将数据元素将数据元素e插入到链队列插入到链队列Q的队尾的队尾 */ */ p=(QNode *)malloc(sizeof(QNode) ;if (!p) return ERROR;/* 申请新结点失败,返回错误标志申请新结点失败,返回错误标志 */p-data=e ; p-next=NULL ; /* 形成新结点形成新结点 */Q.rear-next=p ; Q.

172、rear=p ; /* 新结点插入到队尾新结点插入到队尾 */return OK;咒丰鄙骏该摇煽漠七诉耕玻德饼输找淆搬绸瓦塞颅磋匀工诞口印莎漆壳肯数据结构严蔚敏PPT数据结构严蔚敏PPT 链队列的出队操作链队列的出队操作Status Delete_LinkQueue(LinkQueue *Q, ElemType *x) QNode *p ;if (Q.front=Q.rear) return ERROR ; /* 队空队空 */p=Q.front-next ; /* /* 取队首结点取队首结点 */ */*x=p-data ; Q.front-next=p-next ; /* 修改队首指针修改

173、队首指针 */if (p=Q.rear) Q.rear=Q.front ; /* 当队列只有一个结点时应防止丢失队尾指针当队列只有一个结点时应防止丢失队尾指针 */ free(p) ; return OK ; 揽篙活层寓补螟阅鳞蛙请当储兵讥撼屈剃藕辞灼鼓欺你贡归淑咱筏呕犀莉数据结构严蔚敏PPT数据结构严蔚敏PPT 链队列的撤消链队列的撤消void Destroy_LinkQueue(LinkQueue *Q ) /* 将链队列将链队列Q的队首元素出队的队首元素出队 */ while (Q.front!=NULL) Q.rear=Q.front-next; /* 令尾指针指向队列的第一个结点令尾

174、指针指向队列的第一个结点 */free(Q.front); /* 每次释放一个结点每次释放一个结点 */ /* 第一次是头结点,以后是元素结点第一次是头结点,以后是元素结点 */Q.ront=Q.rear;婉搜府寻睦拾畦任睦态行蓬博切惋神甭摄铡茅建嚎虫采昆纤篮卜捡镰爬拎数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 三三1 设有一个栈,元素进栈的次序为设有一个栈,元素进栈的次序为a, b, c。问经过栈。问经过栈操作后可以得到哪些输出序列?操作后可以得到哪些输出序列?2 循环队列的优点是什么循环队列的优点是什么? ?如何判断它的空和满如何判断它的空和满? ?3 设有一个静态顺序队列,向量大

175、小为设有一个静态顺序队列,向量大小为MAX,判断,判断队列为空的条件是什么?队列满的条件是什么?队列为空的条件是什么?队列满的条件是什么?4 设有一个静态循环队列,向量大小为设有一个静态循环队列,向量大小为MAX,判断,判断队列为空的条件是什么?队列满的条件是什么?队列为空的条件是什么?队列满的条件是什么?5 利用栈的基本操作,利用栈的基本操作,写一个返回栈写一个返回栈S中结点个数的中结点个数的算法算法int StackSize(SeqStack S) ,并说明,并说明S S为何不作为指为何不作为指针参数针参数的算法的算法? ?天荡傣菩掩箱勾屠卑翅脖羚磺卡坡泞守燃丘佳暮褥昧艾但茨烘扔九糟磐瘴数

176、据结构严蔚敏PPT数据结构严蔚敏PPT6 一个双向栈一个双向栈S是在同一向量空间内实现的两个栈是在同一向量空间内实现的两个栈,它们的栈底分别设在向量空间的两端。试为此双向栈设它们的栈底分别设在向量空间的两端。试为此双向栈设计初始化计初始化InitStack(S) ,入栈,入栈Push(S,i,x),出栈,出栈Pop(S,i,x)算法算法,其中,其中i为为0或或1 ,用以表示栈号。,用以表示栈号。7 设设Q0,6是一个静态顺序队列是一个静态顺序队列,初始状态为,初始状态为front=rear=0,请画出做完下列操作后队列的头尾指针,请画出做完下列操作后队列的头尾指针的状态变化情况,若不能入对,请

177、指出其元素,并说明的状态变化情况,若不能入对,请指出其元素,并说明理由。理由。a, b, c, d入队入队a, b, c出队出队i , j , k , l , m入队入队d, i出队出队n, o, p, q, r入队入队茶草巧筒抑逢栖葫拦账喊西蜘沾再祝浆湾幻赔诀尼骑宙谍己畔滚爱氏囊焊数据结构严蔚敏PPT数据结构严蔚敏PPT8 假设假设Q0,5是一个循环队列是一个循环队列,初始状态为,初始状态为front=rear=0,请画出做完下列操作后队列的头尾指针,请画出做完下列操作后队列的头尾指针的状态变化情况,若不能入对,请指出其元素,并说明的状态变化情况,若不能入对,请指出其元素,并说明理由。理由。

178、d, e, b, g, h入队入队d, e出队出队i , j , k , l , m入队入队b出队出队n, o, p, q, r入队入队 钳了佑嗓透晨扫经床躇汇蔑宇彤摔佛屎雌垦奄胶藕丽瑚弦烤辆煮授僻行结数据结构严蔚敏PPT数据结构严蔚敏PPT第第4章章 串串 在非数值处理、事务处理等问题常涉及到一系列在非数值处理、事务处理等问题常涉及到一系列的字符操作。计算机的硬件结构主要是反映数值计算的的字符操作。计算机的硬件结构主要是反映数值计算的要求,因此,字符串的处理比具体数值处理复杂。本章要求,因此,字符串的处理比具体数值处理复杂。本章讨论串的存储结构及几种基本的处理。讨论串的存储结构及几种基本的处

179、理。捕拭作唾轿龋抖傈旗景黍懒级完株巷振覆辊枕详蛀跳躺坟摹当背芯辩果芍数据结构严蔚敏PPT数据结构严蔚敏PPT4.1 串类型的定义串类型的定义4.1.1 串的基本概念串的基本概念 串串( (字符串字符串) ):是零个或多个字符组成的有限序列。:是零个或多个字符组成的有限序列。记作:记作: S=“a1a2a3”,其中,其中S是串名,是串名,ai(1in)是是单个,单个,可以是字母、数字或其它字符。可以是字母、数字或其它字符。 串值串值:双引号括起来的字符序列是串值。:双引号括起来的字符序列是串值。 串长串长:串中所包含的字符个数称为该串的长度。:串中所包含的字符个数称为该串的长度。 空串空串( (

180、空的字符串空的字符串) ):长度为零的串称为空串,它不:长度为零的串称为空串,它不包含任何字符。包含任何字符。 空格串空格串( (空白串空白串) ):构成串的所有字符都是空格的串:构成串的所有字符都是空格的串称为空白串。称为空白串。碎尘岸娃以矿允膳慕敲宏髓癣绝页穷灯葫哑利茵敦袭荒宿给净祸忱谩异修数据结构严蔚敏PPT数据结构严蔚敏PPT注意注意:空串和空白串的不同,例如:空串和空白串的不同,例如“ ”“ ”和和“”“”分别表分别表示长度为示长度为1 1的空白串和长度为的空白串和长度为0的空串。的空串。 子串子串( (substring) ):串中任意个连续字符组成的子:串中任意个连续字符组成的子

181、序列称为该串的子串,包含子串的串相应地称为主串。序列称为该串的子串,包含子串的串相应地称为主串。 子串的序号子串的序号:将子串在主串中首次出现时的该子串:将子串在主串中首次出现时的该子串的首字符对应在主串中的序号,称为子串在主串中的序的首字符对应在主串中的序号,称为子串在主串中的序号(或位置)。号(或位置)。例如,例如,设有串设有串A和和B分别是:分别是: A=“这是字符串这是字符串”,B=“是是”则则B是是A的子串,的子串,A为主串。为主串。B在在A中出现了两次,其中中出现了两次,其中首次出现所对应的主串位置是首次出现所对应的主串位置是3。因此,称。因此,称B在在A中的序中的序号为号为3 。

182、终拖封骗榆娜瑟轴听钩宗埋绰蚁郧肠毕啥离羹畅叉象积倦惑瀑示歹宽薛竿数据结构严蔚敏PPT数据结构严蔚敏PPT 特别地,空串是任意串的子串,任意串是其自身的特别地,空串是任意串的子串,任意串是其自身的子串。子串。 串相等串相等:如果两个串的串值相等:如果两个串的串值相等( (相同相同) ),称这两个,称这两个串相等。换言之,只有当两个串的长度相等,且各个对串相等。换言之,只有当两个串的长度相等,且各个对应位置的字符都相同时才相等。应位置的字符都相同时才相等。 通常在程序中使用的串可分为两种:串变量和串常通常在程序中使用的串可分为两种:串变量和串常量。量。 串常量和整常数、实常数一样,在程序中只能被引

183、串常量和整常数、实常数一样,在程序中只能被引用但不能不能改变其值,即只能读不能写。通常串常量用但不能不能改变其值,即只能读不能写。通常串常量是由直接量来表示的,例如语句错误是由直接量来表示的,例如语句错误(“(“溢出溢出”)”)中中“溢溢出出”是直接量。是直接量。 串变量和其它类型的变量一样,其值是可以改变。串变量和其它类型的变量一样,其值是可以改变。攀经骆击瞎呆卿捕丑惮吹氖丫敌琅钉幼咐漠嫩拿辰年膛邪望摘骄狰集乳钠数据结构严蔚敏PPT数据结构严蔚敏PPT4.1.2 串的抽象数据类型定义串的抽象数据类型定义 ADT String数据对象:数据对象:D = ai|aiCharacterSet, i

184、=1,2,n, n 0 数据关系:数据关系:R = | ai-1, aiD, i=2,3,n 基本操作:基本操作:StrAssign(t , chars)初始条件:初始条件: chars是一个字符串常量。是一个字符串常量。操作结果:生成一个值为操作结果:生成一个值为chars的串的串t 。StrConcat(s, t)初始条件:串初始条件:串s, t 已存在。已存在。揣阿逆跳拘如荡栅擎硕沙搓刽孔崖版厌肥吴莹马热秘锋赘企臣熙址羡江楚数据结构严蔚敏PPT数据结构严蔚敏PPT操作结果:将串操作结果:将串t联结到串联结到串s后形成新串存放到后形成新串存放到s中。中。StrLength(t)初始条件:字

185、符串初始条件:字符串t已存在。已存在。操作结果:返回串操作结果:返回串t中的元素个数,称为串长。中的元素个数,称为串长。SubString (s, pos, len, sub)初始条件:串初始条件:串s, 已存在已存在, 1posStrLength(s)且且 0lenStrLength(s) pos+1。操作结果:用操作结果:用sub返回串返回串s的第的第pos个字符起长度为个字符起长度为len的子串。的子串。 ADT String尿允靶乎屹项氢惠剔侵檄烧占糜怨涂唾咱随臀总毕镍脊窄葬叛该噶匿板仲数据结构严蔚敏PPT数据结构严蔚敏PPT4.2 串的存储表示和实现串的存储表示和实现 串是一种特殊的

186、线性表,其存储表示和线性表类似,串是一种特殊的线性表,其存储表示和线性表类似,但又不完全相同。串的存储方式取决于将要对串所进行但又不完全相同。串的存储方式取决于将要对串所进行的操作。串在计算机中有的操作。串在计算机中有3种表示方式:种表示方式: 定长顺序存储表示定长顺序存储表示:将串定义成字符数组,利用:将串定义成字符数组,利用串名可以直接访问串值。用这种表示方式,串的存串名可以直接访问串值。用这种表示方式,串的存储空间在编译时确定,其大小不能改变。储空间在编译时确定,其大小不能改变。 堆分配存储方式堆分配存储方式:仍然用一组地址连续的存储单:仍然用一组地址连续的存储单元来依次存储串中的字符序

187、列,但串的存储空间是元来依次存储串中的字符序列,但串的存储空间是在程序运行时根据串的实际长度动态分配的。在程序运行时根据串的实际长度动态分配的。 块链存储方式块链存储方式:是一种链式存储结构表示。:是一种链式存储结构表示。姨逮限贮宅骗疮薄状请溅洗涝览涪潞松丧锌眉儿稳乍骇恍挽挡红属嵌痕析数据结构严蔚敏PPT数据结构严蔚敏PPT4.2.1 串的定长串的定长顺序顺序存储表示存储表示 这种存储结构又称为串的顺序存储结构。是用一这种存储结构又称为串的顺序存储结构。是用一组连续的存储单元来存放串中的字符序列。所谓定长顺组连续的存储单元来存放串中的字符序列。所谓定长顺序存储结构,是直接使用定长的字符数组来定

188、义,数组序存储结构,是直接使用定长的字符数组来定义,数组的上界预先确定。的上界预先确定。定长顺序存储结构定义为:定长顺序存储结构定义为:#define MAX_STRLEN 256typedef struct char strMAX_STRLEN ;int length; StringType ; 式拎拧愤徒绕幻豪焕便晦敌额盔凸痹佛诬蓉沤涧诧岂慕雀主钎绳儿你筛胀数据结构严蔚敏PPT数据结构严蔚敏PPT1 串的联结操作串的联结操作Status StrConcat ( StringType s, StringType t)/* 将串将串t联结到串联结到串s之后,结果仍然保存在之后,结果仍然保存在s

189、中中 */ int i, j ;if (s.length+t.length)MAX_STRLEN)Return ERROR ; /* 联结后长度超出范围联结后长度超出范围 */ for (i=0 ; it.length ; i+)s.strs.length+i=t.stri ; /* 串串t联结到串联结到串s之后之后 */s.length=s.length+t.length ; /* 修改联结后的串长度修改联结后的串长度 */return OK ;骇杆溶题墟康羌站姬纪棘之歌锣筹狮蒂菩师她殴答是荔俺空账懂揣桂钉塞数据结构严蔚敏PPT数据结构严蔚敏PPT2 求子串操作求子串操作Status Sub

190、String (StringType s, int pos, int len, StringType *sub) int k, j ;if (poss.length|len(s.length-pos+1)return ERROR ; /* 参数非法参数非法 */sub-length=len-pos+1 ; /* 求得子串长度求得子串长度 */for (j=0, k=pos ; kstrj=s.stri ; /* 逐个字符复制求得子串逐个字符复制求得子串 */return OK ;布楚倘使究榨艾庙咀鼠连掂辽镭叙邢莎厦既敦怒焚默谍巧秘挎您登萍哀烈数据结构严蔚敏PPT数据结构严蔚敏PPT4.2.2

191、串的堆分配存储表示串的堆分配存储表示 实现方法:系统提供一个空间足够大且地址连续的实现方法:系统提供一个空间足够大且地址连续的存储空间存储空间( (称为称为“堆堆”)”)供串使用。可使用供串使用。可使用C语言的动态语言的动态存储分配函数存储分配函数malloc()和和free()来来管理。管理。 特点是:仍然以一组地址连续的存储空间来存储字特点是:仍然以一组地址连续的存储空间来存储字符串值,但其所需的存储空间是在程序执行过程中动态符串值,但其所需的存储空间是在程序执行过程中动态分配,故是动态的,变长的。分配,故是动态的,变长的。串的堆式存储结构的类型定义串的堆式存储结构的类型定义typedef

192、 struct char *ch; /* 若非空,按长度分配,否则为若非空,按长度分配,否则为NULL */int length; /* 串的长度串的长度 */ HString ;氖礼浆螟困骄赵毒蝗芭降傣娠个因仆宿厂碳商罩方砍百焊百播方较感载苍数据结构严蔚敏PPT数据结构严蔚敏PPT1 串的联结操作串的联结操作Status Hstring *StrConcat(HString *T, HString *s1, HString *s2)/* 用用T返回由返回由s1和和s2联结而成的串联结而成的串 */ int k, j , t_len ; if (T.ch) free(T); /* 释放旧空间释

193、放旧空间 */t_len=s1-length+s2-length ;if (p=(char *)malloc(sizeof(char)*t_len)=NULL) printf(“系统空间不够,申请空间失败系统空间不够,申请空间失败 !n”) ; return ERROR ; for (j=0 ; jlength; j+) T-chj=s1-chj ; /* 将串将串s复制到串复制到串T中中 */尿然漏渠卧玛膘纳汹授饮垒玛投箔屏密杏清蛋盛蜒瞧阂诅思仗擞慢朽矫哲数据结构严蔚敏PPT数据结构严蔚敏PPTfor (k=s1-length, j=0 ; jlength; k+, j+) T-chj=s1

194、-chj ; /* 将串将串s2复制到串复制到串T中中 */free(s1-ch) ; free(s2-ch) ; return OK ; 转黄包药挛逐掉波牡够梁溃展池酝鸦巢盼打摹召阉酿乐真冬缔枫斯骆庸洱数据结构严蔚敏PPT数据结构严蔚敏PPT4.2.3 串的链式存储表示串的链式存储表示 串的链式存储结构和线性表的串的链式存储结构类串的链式存储结构和线性表的串的链式存储结构类似,采用单链表来存储串,似,采用单链表来存储串,结点的构成是:结点的构成是: data域:存放字符,域:存放字符,data域可存放的字符个数称为域可存放的字符个数称为结点的大小;结点的大小; next域:存放指向下一结点的

195、指针。域:存放指向下一结点的指针。 若每个结点仅存放一个字符,则结点的指针域就非若每个结点仅存放一个字符,则结点的指针域就非常多,造成系统空间浪费,为节省存储空间,考虑串结常多,造成系统空间浪费,为节省存储空间,考虑串结构的特殊性,使每个结点存放若干个字符,这种结构称构的特殊性,使每个结点存放若干个字符,这种结构称为块链结构。如为块链结构。如图图4-1是块大小为是块大小为3的串的块链式存储结的串的块链式存储结构示意图。构示意图。枢晰街州谭金聋莫倚什尖妒邦橡篱脆溜项乘姑窝吏剂哄吐优驱竖趴昭苇锅数据结构严蔚敏PPT数据结构严蔚敏PPT串的块链式存储的类型定义包括:串的块链式存储的类型定义包括: 块

196、结点的类型定义块结点的类型定义#define BLOCK_SIZE 4typedef struct Blstrtype char dataBLOCK_SIZE ;struct Blstrtype *next;BNODE ;a b c e p c g head图图4-1 串的块链式存储结构示意图串的块链式存储结构示意图颠磊垛扒患漓还缔痞处愉呈娥昏你擒幌屋辙皮酵唇乞斯芳帚北鼻屈辆扛灾数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 块链串的类型定义块链串的类型定义typedef struct BNODE head; /* 头指针头指针 */ int Strlen ; /* 当前长度当前长度 */ B

197、lstring ; 在这种存储结构下,结点的分配总是完整的结点为在这种存储结构下,结点的分配总是完整的结点为单位,因此,为使一个串能存放在整数个结点中,在串单位,因此,为使一个串能存放在整数个结点中,在串的末尾填上不属于串值的特殊字符,以表示串的终结。的末尾填上不属于串值的特殊字符,以表示串的终结。 当一个块当一个块(结点结点)内存放多个字符时,往往会使操作内存放多个字符时,往往会使操作过程变得较为复杂,如在串中插入或删除字符操作时通过程变得较为复杂,如在串中插入或删除字符操作时通常需要在块间移动字符。常需要在块间移动字符。岁抨耐亡忙颓乳咏钉拼昔泉铝阐腹扫朴汝锦武皮裹论徐钞堵蒜许渡及篱潭数据结

198、构严蔚敏PPT数据结构严蔚敏PPT4.3 串的模式匹配算法串的模式匹配算法模式匹配模式匹配( (模范匹配模范匹配) ):子串在主串中的定位称为模子串在主串中的定位称为模式匹配或串匹配式匹配或串匹配( (字符串匹配字符串匹配) ) 。模式匹配成功是指在。模式匹配成功是指在主串主串S中能够找到模式串中能够找到模式串T,否则,称模式串,否则,称模式串T在主串在主串S中不存在。中不存在。 模式匹配的应用在非常广泛。例如,在文本编辑程模式匹配的应用在非常广泛。例如,在文本编辑程序中,我们经常要查找某一特定单词在文本中出现的位序中,我们经常要查找某一特定单词在文本中出现的位置。显然,解此问题的有效算法能极

199、大地提高文本编辑置。显然,解此问题的有效算法能极大地提高文本编辑程序的响应性能。程序的响应性能。 模式匹配是一个较为复杂的串操作过程。迄今为止,模式匹配是一个较为复杂的串操作过程。迄今为止,人们对串的模式匹配提出了许多思想和效率各不相同的人们对串的模式匹配提出了许多思想和效率各不相同的计算机算法。介绍两种主要的模式匹配算法。计算机算法。介绍两种主要的模式匹配算法。垒学订止获射瘦娠殴咬椿框屉弱秦茧浸旗襄绳遏差博队舷券榆喘糊灸莽蒜数据结构严蔚敏PPT数据结构严蔚敏PPT4.3.1 Brute-Force模式匹配算法模式匹配算法 设设S为目标串,为目标串,T为模式串,且不妨设:为模式串,且不妨设:S

200、=“s0s1s2sn-1” , T=“t0t1t2 tm-1” 串的匹配实际上是对合法的位置串的匹配实际上是对合法的位置0in-m依次将目依次将目标串中的子串标串中的子串sii+m-1和模式串和模式串t0m-1进行比较:进行比较: 若若sii+m-1=t0m-1:则称从位置:则称从位置i开始的匹开始的匹配成功,亦称模式配成功,亦称模式t在目标在目标s中出现;中出现; 若若sii+m-1t0m-1:从:从i开始的匹配失败。开始的匹配失败。位置位置i称为位移,当称为位移,当sii+m-1=t0m-1时,时,i称为称为有效位移;当有效位移;当sii+m-1 t0m-1时,时,i称为无效称为无效位移。

201、位移。起哭仇岔润缘钢雄骚川之逾胰澎扛莫改淮绦蛮另泞亡蔗跺颓召颓蔗线桓撩数据结构严蔚敏PPT数据结构严蔚敏PPT 这样,串匹配这样,串匹配问题可简化为找出某给定模式问题可简化为找出某给定模式T在给在给定目标串定目标串S中首次出现中首次出现的有效位移。的有效位移。算法实现算法实现int IndexString(StringType s , StringType t , int pos ) /* 采用顺序存储方式存储主串采用顺序存储方式存储主串s和模式和模式t, */ /* 若模式若模式t在主串在主串s中从第中从第pos位置开始有匹配的子串,位置开始有匹配的子串,*/ /* 返回位置,否则返回返回位

202、置,否则返回-1 */ char *p , *q ;int k , j ;k=pos-1 ; j=0 ; p=s.str+pos-1 ; q=t.str ; /* 初始匹配位置设置初始匹配位置设置 */ /* 顺序存放时第顺序存放时第pos位置的下标值为位置的下标值为pos-1 */眷帮悔原缺砂润蛀抿赊末顿沈孩剃刹堪束冤空雄祥种惜填渡汝液善啡觉里数据结构严蔚敏PPT数据结构严蔚敏PPTwhile (ks.length)&(jt.length) if (*p=*q) p+ ; q+ ; k+ ; j+ ; else k=k-j+1 ; j=0 ; q=t.str ; p=s.str+k ; /*

203、 重新设置匹配位置重新设置匹配位置 */if (j=t.length) return(k-t.length) ; / * 匹配,返回位置匹配,返回位置 */else return(-1) ; /* 不匹配,返回不匹配,返回-1 */潘鲜工财篓阳寄扫巢减却曝寄恍札个跟剐下燕伍钟拯止为桨茄缚映叼握梦数据结构严蔚敏PPT数据结构严蔚敏PPT 该算法简单,易于理解。在一些场合的应用里,如该算法简单,易于理解。在一些场合的应用里,如文字处理中的文本编辑,其效率较高。文字处理中的文本编辑,其效率较高。 该算法的时间复杂度为该算法的时间复杂度为O(n*m) ,其中,其中n 、m分别是分别是主串和模式串的长度

204、。通常情况下,实际运行过程中,主串和模式串的长度。通常情况下,实际运行过程中,该算法的执行时间近似于该算法的执行时间近似于O(n+m) 。理解该算法的关键点理解该算法的关键点 当第一次当第一次sktj时:主串要退回到时:主串要退回到k-j+1的位置,而模的位置,而模式串也要退回到第一个字符(即式串也要退回到第一个字符(即j=0的位置)。的位置)。比较出现比较出现sktj时:则应该有时:则应该有sk-1=tj-1,sk-j+1=t1, sk-j=t0 。银肆诞间杰碉梗士溃晚丧尖亡蓉羹源幌盛慧蹿羡宣九绸彭铃朽杨三榷匿穆数据结构严蔚敏PPT数据结构严蔚敏PPT4.3.2 模式匹配的一种改进算法模式匹

205、配的一种改进算法 该改进算法是由该改进算法是由D.E.Knuth ,J.H.Morris和和 V.R.Pratt提出来的,简称为提出来的,简称为KMP算法。其算法。其改进在于:改进在于: 每当一趟匹配过程出现字符不相等时,主串指示器每当一趟匹配过程出现字符不相等时,主串指示器不用回溯,而是利用已经得到的不用回溯,而是利用已经得到的“部分匹配部分匹配”结果,将结果,将模式串的指示器向右模式串的指示器向右“滑动滑动”尽可能远的一段距离后,尽可能远的一段距离后,继续进行比较。继续进行比较。例:例:设有串设有串s=“abacabab” ,t=“abab” 。则第一次匹配。则第一次匹配过程如图过程如图4

206、-2所示。所示。图图4-2 模式匹配示例模式匹配示例 s=“a b cbb” i=3 | | 匹配失败 t=“a b b” j=3跳歧据彪原埃姑剂谚鼻撇口署谰尊敞刺故芽孽限厌身欠驶块湿幸霹承逛息数据结构严蔚敏PPT数据结构严蔚敏PPT 在在i=3和和j=3时,匹配失败。但重新开始第二次匹配时,匹配失败。但重新开始第二次匹配时,不必从时,不必从i=1 ,j=0开始。因为开始。因为s1=t1,t0t1,必有,必有s1t0,又因为,又因为t0=t2,s2=t2,所以必有,所以必有s2=t0。由此可知,第二。由此可知,第二次匹配可以直接从次匹配可以直接从i=3 、j=1开始。开始。 总之,在主串总之,

207、在主串s与模式串与模式串t的匹配过程中,一旦出现的匹配过程中,一旦出现sitj ,主串,主串s的指针不必回溯,而是直接与模式串的的指针不必回溯,而是直接与模式串的tk(0kj进行比较,而进行比较,而k的取值与主串的取值与主串s无关,只与模式无关,只与模式串串t本身的构成有关,即从模式串本身的构成有关,即从模式串t可求得可求得k值。值。)冰蚤呆男函甚俱逐喊输每馈叔吁哈师翌摄宇甸熙难迈讹止骇钵匿碰磁鬃汗数据结构严蔚敏PPT数据结构严蔚敏PPT 不失一般性,设不失一般性,设主串主串s=“s1s2sn” ,模式串模式串t=“t1 t2 tm” 。 当当sitj(1in-m,1jm,mn)时,主串时,主

208、串s的指的指针针i不必回溯,而模式串不必回溯,而模式串t的指针的指针j回溯到第回溯到第k(kk满足满足4-1式。式。t1t2tk-1= si-(k-1) si-(k-2) si-2 si-1 (4-1)而已经得到的而已经得到的 “部分匹配部分匹配”的结果为:的结果为:tj-(k-1) tj-k tj-1=si-(k-1) si-(k-2) si-2 si-1 (4-2)由式由式(4-1)和式和式(4-2)得:得:t1t2tk-1=tj-(k-1) tj-k tj-1 (4-3) 该推导过程可用图该推导过程可用图4-3形象描述。实际上,式形象描述。实际上,式(4-3)描述了模式串中存在相互重叠的

209、子串的情况。描述了模式串中存在相互重叠的子串的情况。弥庇补丈斌肇絮盆痞拯妥半圾洱体习裙蚌臆毋碱北跌暂柯养私啮聘巩雏徒数据结构严蔚敏PPT数据结构严蔚敏PPT图图4-3 KMP算法示例算法示例主串si模式串tkj0 当当j=1时时Maxk|1kjt1t2tk-1=tj-(k-1) tj-k tj-1 该集合不空时该集合不空时1 其它情况其它情况nextj=定义定义nextj函数为函数为畴衷役峪坏述蓬拭把嚷羽每瞳节寇壤冲忱致午脉商少剧球醋灸栏驾需患胚数据结构严蔚敏PPT数据结构严蔚敏PPT在求得了在求得了nextj值之后,值之后,KMP算法的思想是:算法的思想是: 设目标串设目标串(主串主串)为为

210、s,模式串为,模式串为t ,并设,并设i指针和指针和j指针指针分别指示目标串和模式串中正待比较的字符,设分别指示目标串和模式串中正待比较的字符,设i和和j的的初值均为初值均为1。若有。若有si=tj,则,则i和和j分别加分别加1。否则,。否则,i不变,不变,j退回到退回到j=nextj的位置,再比较的位置,再比较si和和tj,若相等,则,若相等,则i和和j分别加分别加1。否则,。否则,i不变,不变,j再次退回到再次退回到j=nextj的位置,的位置,依此类推。直到下列两种可能:依此类推。直到下列两种可能:(1) j退回到某个下一个退回到某个下一个j值时字符比较相等,则指值时字符比较相等,则指针

211、各自加针各自加1继续进行匹配。继续进行匹配。(2)退回到退回到j=0,将,将i和和j分别加分别加1,即从主串的下一个字符,即从主串的下一个字符si+1模式串的模式串的t1重新开始匹配。重新开始匹配。KMP算法如下算法如下瓤许涂擂务育发谁唾币膜揍碱本啤掳君医显肮撂蜒萌步粥搬骸蹲京闽猾存数据结构严蔚敏PPT数据结构严蔚敏PPT#define Max_Strlen 1024int nextMax_Strlen;int KMP_index (StringType s , StringType t) /* 用用KMP算法进行模式匹配,匹配返回位置,否则返回算法进行模式匹配,匹配返回位置,否则返回-1 *

212、/ /*用静态存储方式保存字符串,用静态存储方式保存字符串, s和和t分别表示主串和模式串分别表示主串和模式串 */ int k=0 , j=0 ; /*初始匹配位置设置初始匹配位置设置 */while (ks.length)&(j= t.length) return(k-t.length) ; else return(-1) ; 垮鹊杜匠氰偿柑辊五倔祖悦押肘博至鲸电叙抵柬诚斋爵沿抵味钨懈矿凛敌数据结构严蔚敏PPT数据结构严蔚敏PPT 很显然,很显然,KMP_index函数是在已知下一个函数值的函数是在已知下一个函数值的基础上执行的,以下讨论如何求基础上执行的,以下讨论如何求next函数值函数

213、值? 由式由式(4-3)知,求模式串的知,求模式串的nextj值与主串值与主串s无关,无关,只与模式串只与模式串t本身的构成有关,则可把求本身的构成有关,则可把求next函数值的问函数值的问题看成是一个模式匹配问题。由题看成是一个模式匹配问题。由next函数定义可知:函数定义可知:当当j=1时:时:next1=0。设设nextj=k,即在模式串中存在:,即在模式串中存在:t1t2tk-1=tj-(k-1)tj-k tj-1 ,其中下标,其中下标k满足满足1kk满足上式,即:满足上式,即:nextj+1=nextj+1=k+1墟爽叫厨请票饲龄鸳姨峙乾揭哉鹿掂守顺栏评拇做首匀修琢厢徘嫡响且吕数据结

214、构严蔚敏PPT数据结构严蔚敏PPT(2) 若有若有tktj :则表明在模式串中有:则表明在模式串中有:t1 t2tk-1 tktj-(k-1) tj-k tj-1 tj ,当,当tktj时应时应将模式向右滑动将模式向右滑动至以至以模式中的第模式中的第nextk个字符和主串中的第个字符和主串中的第j个字符相比个字符相比较。若较。若nextk= k,且,且tj = tk,则说明在主串中第,则说明在主串中第j+1字符之前存在一个长度为字符之前存在一个长度为k(即即nextk)的最长子串,的最长子串,与模式串中从第一个字符起长度为与模式串中从第一个字符起长度为k的子串相等。的子串相等。即即 nextj

215、+1=k+1 同理,若同理,若tjtk,应,应将模式继续向右滑动将模式继续向右滑动至将模式中至将模式中的第的第nextk个字符和个字符和tj对齐,对齐,依此类推,直到,依此类推,直到tj和和模式串中的某个字符匹配成功或者不存在任何模式串中的某个字符匹配成功或者不存在任何k(1 kj)满足等式:满足等式:t1 t2tk-1 tk=tj-(k-1) tj-k tj-1 tj 则:则: nextj+1=1鼠末潭嫁难宙累络刃挽婚育被柴络吸娃茧岔套究押天耙搐阀线搀紫鄙匪烽数据结构严蔚敏PPT数据结构严蔚敏PPT根据上述分析,根据上述分析, 求求next函数值的算法如下:函数值的算法如下:void nex

216、t(StringType t , int next) /* 求模式求模式t的的next串串t函数值并保存在函数值并保存在next数组中数组中 */ int k=1 , j=0 ; next1=0;while (k1)个具有相同数据类型的数据元素个具有相同数据类型的数据元素a1,a2,an组成的有序序列组成的有序序列,且该,且该序列必须存储在一序列必须存储在一块地址连续的存储单元中块地址连续的存储单元中。 数组中的数据元素数组中的数据元素具有相同数据类型具有相同数据类型。 数组是一种随机存取结构,给定一组下标,就可数组是一种随机存取结构,给定一组下标,就可以访问与其对应的数据元素。以访问与其对应

217、的数据元素。 数组中的数据元素个数是固定的。数组中的数据元素个数是固定的。剧谣店软呼颤英硒宏赠死边惊洁琴摈宿昼旁困屁求沥讼紊权坡预滩摔六皋数据结构严蔚敏PPT数据结构严蔚敏PPT5.1.1 数组的数组的抽象数据类型定义抽象数据类型定义 1 抽象数据类型定义抽象数据类型定义 ADT Array数据对象:数据对象:ji= 0,1,bi-1 , 1,2, ,n ; D = aj1j2jn | n0称为数组的维数称为数组的维数,b bi是数组第是数组第i维的维的长度长度,ji是数组元素是数组元素第第i维的下标维的下标,aj1j2jnElemSet 数据关系:数据关系:R = R1, R2, , RnR

218、i=|0jkbk-1 , 1kn且且ki,0jibi-2, aj1j2 ji+1jnD 基本操作:基本操作: ADT Array噎桓保裤攫控伪缚里园做玖网绷夷哨吟苯紊骆摈啼挚挥致融饱唆哮墨抓瑶数据结构严蔚敏PPT数据结构严蔚敏PPT 由上述定义知由上述定义知,n维数组中有维数组中有b1 b2 bn个数据个数据元素元素,每个数据元素都受到每个数据元素都受到n维关系的约束维关系的约束。2 直观的直观的n维数组维数组 以二维数组为例讨论。将以二维数组为例讨论。将二维数组看成是一个定长二维数组看成是一个定长的线性表的线性表,其其每个元素又是一个定长的线性表每个元素又是一个定长的线性表。 设二维数组设二

219、维数组A=(aij)m n,则,则 A=(1,2,p) (p=m或或n)其中每个数据元素其中每个数据元素j是一个列向量是一个列向量(线性表线性表) : j =(a1j ,a2j ,amj) 1jn或或是一个行向量是一个行向量: i =(ai1 ,ai2 ,ain) 1im如图如图5-1所示。所示。歌皖钓掐刊郸管厩市垦微琼弓念岳锡充拇撬骏羡阁咱莎偏峦示钩扶恰挎偿数据结构严蔚敏PPT数据结构严蔚敏PPT a11 a12 a1n a21 a22 a2n am1 am2 amnA= A=a11 a12 a1na21 a22 a2nam1 am2 amna11 a21 am1a12 a22 am2a1n

220、 a2n amnA=图图5-1 二维数组图二维数组图例形式例形式(a) 矩阵矩阵表示形式表示形式(b) 列向量的一维数组形式列向量的一维数组形式(c) 行向量的一维数组形式行向量的一维数组形式慨忠窗谐蠢铜香咱妹红壹介镁搬夷圣疟瞄色逼脊纠仟客苞模煤帆写膘但芥数据结构严蔚敏PPT数据结构严蔚敏PPT5.2 数组的数组的顺序表示和实现顺序表示和实现 数组一般不做插入和删除操作,也就是说,数组数组一般不做插入和删除操作,也就是说,数组一旦建立,结构中的元素个数和元素间的关系就不再发一旦建立,结构中的元素个数和元素间的关系就不再发生变化。因此,一般都是生变化。因此,一般都是采用顺序存储的方法来表示数采用

221、顺序存储的方法来表示数组组。 问题问题:计算机的计算机的内存结构是一维内存结构是一维( (线性线性) )地址结构地址结构,对于多维数组,将其存放对于多维数组,将其存放( (映射映射) )到内存一维结构时,有到内存一维结构时,有个个次序约定问题次序约定问题。即必须按某种次序将数组元素排成一。即必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放到内存中。列序列,然后将这个线性序列存放到内存中。 二维数组是最简单的多维数组,以此为例说明多维二维数组是最简单的多维数组,以此为例说明多维数组存放数组存放( (映射映射) )到内存一维结构时的到内存一维结构时的次序约定问题次序约定问题。梳芹弓茁今

222、泌政纺栽索逸坪茁质捕翰遮术拈贵之僳现额斑迂燎樱淳神队吉数据结构严蔚敏PPT数据结构严蔚敏PPT通常有两种顺序存储方式通常有两种顺序存储方式 行优先顺序行优先顺序(Row Major Order) :将数组元素将数组元素按行排列,第按行排列,第i+1个行向量紧接在第个行向量紧接在第i个行向量后面。对个行向量后面。对二维数组,按行优先顺序存储的线性序列为:二维数组,按行优先顺序存储的线性序列为: a11,a12,a1n, a21,a22,a2n , am1,am2,amn PASCAL、C是按行优先顺序存储的,如图是按行优先顺序存储的,如图5-2(b)示。示。 列优先顺序列优先顺序(Column

223、Major Order) :将数组将数组元素按列向量排列,第元素按列向量排列,第j+1个列向量紧接在第个列向量紧接在第j个列向量个列向量之后,对二维数组,按列优先顺序存储的线性序列为:之后,对二维数组,按列优先顺序存储的线性序列为: a11,a21,am1, a12,a22,am2, , an1,an2,anm FORTRAN是按列优先顺序存储的,如图是按列优先顺序存储的,如图5-2(c)。墙丝郊爷混珍助萌腑狼距我哇未灯淌沿巴羽缅绣卉掳潮写圣歹枉漂倾倪磅数据结构严蔚敏PPT数据结构严蔚敏PPT图图5-2 二维数组及其顺序存储图二维数组及其顺序存储图例形式例形式 a11 a12 a1n a21

224、a22 a2n am1 am2 amnA=(a) 二维数组的表示形二维数组的表示形式式(b) 行优先顺序存行优先顺序存储储(c) 列列优先顺序存优先顺序存储储a11 a12 a1n第第 1行行a21 a22 a2n第第 2行行am1 am2 Amn 第第 m行行a11 a21 am1第第 1列列a12 a22 am2第第 2列列a1m a2m amn第第 n列列承颐裕琶舍溶楷舱咆亏瓦靳血枣龟府伺批讳弘思廊滑湃长恩华妒拂念措打数据结构严蔚敏PPT数据结构严蔚敏PPT 设有二维数组设有二维数组A=(aij)m n,若每个元素占用的存储单,若每个元素占用的存储单元数为元数为l( (个个) ),LOC

225、a11表示元素表示元素a11的首地址的首地址,即,即数组数组的的首地址首地址。1 以以“行优先顺序行优先顺序”存储存储 第第1行中的行中的每个元素对应的每个元素对应的( (首首) )地址是:地址是: LOCa1j=LOCa11+(j-1) l j=1,2, ,n(2) 第第2行中的行中的每个元素对应的每个元素对应的( (首首) )地址是:地址是: LOCa2j=LOCa11+n l +(j-1) l j=1,2, ,n 第第m行中的行中的每个元素对应的每个元素对应的( (首首) )地址是:地址是:LOCamj=LOCa11+(m-1) n l +(j-1) l j=1,2, ,n 盟正仟侯截顾

226、乎射葡纱燃屹供文啡梭队震氛妖卫轻意坊混慧调共抢托紧慎数据结构严蔚敏PPT数据结构严蔚敏PPT 由此可知由此可知,二维数组中,二维数组中任一元素任一元素aij的的( (首首) )地址地址是:是:LOCaij=LOCa11+(i-1) n +(j-1) l (5-1)i=1,2, ,m j=1,2, ,n 根据根据(5-1)式式,对于三维数组,对于三维数组A=(aijk)m n p,若每个,若每个元素占用的存储单元数为元素占用的存储单元数为l( (个个) ),LOCa111表示元素表示元素a111的首地址的首地址,即,即数组的数组的首地址首地址。以以“行优先顺序行优先顺序”存储在存储在内存中内存中

227、。 三维数组中任一元素三维数组中任一元素aijk的的( (首首) )地址是:地址是: LOC(aijk)=LOCa111+(i-1) n p+(j-1) p+(k-1) l (5-2) 推而广之推而广之,对,对n维数组维数组A=(aj1j2jn) ,若每个元素占,若每个元素占用的存储单元数为用的存储单元数为l( (个个) ),LOCa11 1表示元素表示元素a11 1的的首地址首地址。则。则 以以“行优先顺序行优先顺序”存储在内存中存储在内存中。悦讳朱琵兽粱滩陀韵撑郸透荤厚锌鼠诉挝捞纪夯窒名闷堑秋戏务嗓链凄读数据结构严蔚敏PPT数据结构严蔚敏PPT n维数组中任一元素维数组中任一元素aj1j2

228、jn的的( (首首) )地址是:地址是: LOCaj1j2jn=LOCa11 1+(b2 bn) (j1-1) + (b3 bn) (j2-1)+ + bn (jn-1-1)+ (jn-1) l (5-3)霸扦栏此粉打捶卫吼嘿皖乘遇夷鲍载蹿鸣臼卓朝拾歹纹憨浙雷炔颅笛犁捆数据结构严蔚敏PPT数据结构严蔚敏PPT2 以以“列优先顺序列优先顺序”存储存储 第第1列中的列中的每个元素对应的每个元素对应的( (首首) )地址是:地址是: LOCaj1=LOCa11+(j-1) l j=1,2, ,m(2) 第第2列中的列中的每个元素对应的每个元素对应的( (首首) )地址是:地址是: LOCaj2=LO

229、Ca11+m l +(j-1) l j=1,2, ,m 第第n列中的列中的每个元素对应的每个元素对应的( (首首) )地址是:地址是:LOCajn=LOCa11+ (n-1) m l +(j-1) l j=1,2, ,m 由此可知由此可知,二维数组中,二维数组中任一元素任一元素aij的的( (首首) )地址地址是:是:LOCaij=LOCa11+(i-1) m+(j-1) l (5-1)i=1,2, ,n j=1,2, ,m 逃蜗晤诸吟淖恩浸端躇反队准梅惶樟唾仑豆伤但严菠坝袭均赏有镜氖戒徘数据结构严蔚敏PPT数据结构严蔚敏PPT5.3 矩阵的压缩存储矩阵的压缩存储 在科学与工程计算问题中,矩阵

230、是一种常用的数学在科学与工程计算问题中,矩阵是一种常用的数学对象,在高级语言编程时,通常将一个矩阵描述为一个对象,在高级语言编程时,通常将一个矩阵描述为一个二维数组。这样,可以对其元素进行随机存取,各种矩二维数组。这样,可以对其元素进行随机存取,各种矩阵运算也非常简单。阵运算也非常简单。 对于对于高阶矩阵高阶矩阵,若其中,若其中非零元素呈某种规律分布非零元素呈某种规律分布或或者者矩阵中有大量的零元素矩阵中有大量的零元素,若仍然用常规方法存储,可,若仍然用常规方法存储,可能存储重复的非零元素或零元素,将造成存储空间的大能存储重复的非零元素或零元素,将造成存储空间的大量浪费。对这类矩阵进行压缩存储

231、:量浪费。对这类矩阵进行压缩存储: 多个相同的非零元素只分配一个存储空间多个相同的非零元素只分配一个存储空间; 零元素不分配空间。零元素不分配空间。庄颜络氧修效踞满基怜逮撕铁郭未辞巧镊柑偿继叠薯掂卧肚荒箕轮研孽第数据结构严蔚敏PPT数据结构严蔚敏PPT5.3.1 特殊矩阵特殊矩阵特殊矩阵特殊矩阵:是指非零元素或零元素的分布有一定规律是指非零元素或零元素的分布有一定规律的矩阵。的矩阵。1 对称矩阵对称矩阵 若一个若一个n阶方阵阶方阵A=(aij)n n中的元素满足性质:中的元素满足性质:aij=aji 1i,jn且且ij则称则称A为对称矩阵,如图为对称矩阵,如图5-3所示。所示。图图5-3 对称

232、矩阵示例对称矩阵示例1 5 1 3 73 0 2 5 17 0 6 1 35 0 8 0 01 8 9 2 6A= a11 a21 a22 a31 a32 a33 an1 an2 annA=牌鸣吩皖遗演意若颜反扁党敌萝戎牌家潞讲么欣鹏呸佃蛀他贴起杭朽超富数据结构严蔚敏PPT数据结构严蔚敏PPT 对称矩阵中的对称矩阵中的元素关于主对角线对称元素关于主对角线对称,因此,让,因此,让每一对对称元素每一对对称元素aij和和aji(ij)分配一个存储空间,则分配一个存储空间,则n2个元素压缩存储到个元素压缩存储到n(n+1)/2个存储空间,能节约近一半个存储空间,能节约近一半的存储空间。的存储空间。 不

233、失一般性,假设按不失一般性,假设按“行优先顺序行优先顺序”存储下三角形存储下三角形( (包括对角线包括对角线) )中的元素。中的元素。 设用一维数组设用一维数组( (向量向量) )sa0n(n+1)/2存储存储n阶对称阶对称矩阵,如图矩阵,如图5-4所示。为了便于访问,必须找出矩阵所示。为了便于访问,必须找出矩阵A中中的元素的下标值的元素的下标值(i,j)和向量和向量sak的的下标值下标值k之间的对之间的对应关系。应关系。sa a11 a21 a22 a31 a32 a33 an1 an2 annK 1 2 3 4 n(n-1)/2 n(n+1)/2图图5-4 对称矩阵的对称矩阵的压缩存储示例

234、压缩存储示例沂娇沽戚昌楞蹈释锯兽又四仲挨卷瘁倒暴柬嫩浚渔篷獭壤寂猎炕晰据揭桓数据结构严蔚敏PPT数据结构严蔚敏PPT 若若ij:ai j在下三角形中,直接保存在在下三角形中,直接保存在sa中。中。ai j之之前的前的i-1行共有元素个数:行共有元素个数: 1+2+(i-1)=i (i-1)/2而在第而在第i行上,行上,ai j之前恰有之前恰有j-1个元素,因此,元素个元素,因此,元素ai j保保存存在向量在向量sa中时的中时的下标值下标值k之间的对应关系之间的对应关系是:是: k=i (i-1)/2+j-1 ij 若若ij:则:则aij是在上三角矩阵中。因为是在上三角矩阵中。因为aij=aji

235、,在向,在向量量sa中保存的是中保存的是aji 。依上述分析可得:。依上述分析可得: k=j (j-1)/2+i-1 ij 对称矩阵元素对称矩阵元素ai j保存保存在向量在向量sa中时的中时的下标值下标值k与与(i,j)之间的对应关系)之间的对应关系是:是: i (i-1)/2+j-1 当当ij时时j (j-1)/2+i-1 当当ij时时K=1i,j n (5-4)忆启缸对伐候所血印坤腻关溢矫榴或无禹豁悉疯盖灰软垂涂锤彤谬巴宏纯数据结构严蔚敏PPT数据结构严蔚敏PPT 根据上述的下标对应关系,对于矩阵中的任意元根据上述的下标对应关系,对于矩阵中的任意元素素aij,均可在一维数组,均可在一维数组

236、sa中唯一确定其位置中唯一确定其位置k;反之,反之,对所有对所有k=1,2, ,n(n+1)/2,都能确定,都能确定sak中的元素在中的元素在矩阵中的位置矩阵中的位置(i,j)。 称称sa0n(n+1)/2为为n阶对称矩阵阶对称矩阵A的压缩存储。的压缩存储。2 三角矩阵三角矩阵 以主对角线划分,三角矩阵有上三角和下三角两以主对角线划分,三角矩阵有上三角和下三角两种。种。 上三角矩阵的下三角(不包括主对角线)中的元素上三角矩阵的下三角(不包括主对角线)中的元素均为常数均为常数c( (一般为一般为0) )。下三角矩阵正好相反,它的主对。下三角矩阵正好相反,它的主对角线上方均为常数,如图角线上方均为

237、常数,如图5-5所示。所示。纹矗菠楔改焰念剂笛翰贷托枣冀薪掀鼠属雷艇吝存傀绒诉芥啮鸽哨蠢绦祸数据结构严蔚敏PPT数据结构严蔚敏PPTa11 a12 a1nc a22 a2nc c ann a11 c ca21 a22 can1 an2 ann 图图5-5 三角矩阵三角矩阵示例示例(b) 下下三角矩阵三角矩阵示例示例(a) 上上三角矩阵三角矩阵示例示例 三角矩阵中的重复元素三角矩阵中的重复元素c可共享一个存储空间,其可共享一个存储空间,其余的元素正好有余的元素正好有n(n+1)/2个,因此,三角矩阵可压缩存个,因此,三角矩阵可压缩存储到向量储到向量sa0n(n+1)/2中,其中中,其中c存放在向

238、量的第存放在向量的第1个个分量中。分量中。 上三角矩阵元素上三角矩阵元素ai j保存保存在向量在向量sa中时的中时的下标值下标值k与与(i,j)之间的对应关系)之间的对应关系是:是:撬侈啡照尾褪摇傣催森证隅蜀闺虑绝砍耳喳霉涕捉堕蛰拇弗赢照评捉矾陈数据结构严蔚敏PPT数据结构严蔚敏PPT 下三角矩阵元素下三角矩阵元素ai j保存保存在向量在向量sa中时的中时的下标值下标值k与与(i,j)之间的对应关系)之间的对应关系是:是:i (i-1)/2+j-1 当当ij时时n (n+1)/2 当当ij时时K=1i,jn (5-6)3 对角矩阵对角矩阵 矩阵中,除了主对角线和主对角线上或下方若干矩阵中,除了

239、主对角线和主对角线上或下方若干条对角线上的元素之外,其余元素皆为零。即所有的非条对角线上的元素之外,其余元素皆为零。即所有的非零元素集中在以主对角线为了中心的带状区域中,如图零元素集中在以主对角线为了中心的带状区域中,如图5-6所示。所示。秧厕爷桩纺莱舱求载还妇卜官孔职持僳寐袒狭甫倚顽谩潍控绎缎雾栏吻发数据结构严蔚敏PPT数据结构严蔚敏PPTa11 a12 0 . 0a21 a22 a23 0 . 00 a32 a33 a34 0 . 0 . 0 . 0 0 an n-1 an n0 . 0 an-1 n-2 an-1 n-1 an-1 nA=图图5-6 三对角矩阵三对角矩阵示例示例 如上图三

240、对角矩阵,非零元素仅出现在主对角如上图三对角矩阵,非零元素仅出现在主对角(ai i,1in)上、主对角线上的那条对角线上、主对角线上的那条对角线(ai i+1,1in-1) 、主对角线下的那条对角线上、主对角线下的那条对角线上(ai+1 i,1in-1)。显然,当。显然,当| i-j |1时,元素时,元素aij=0。 由此可知,一个由此可知,一个k对角矩阵对角矩阵( (k为奇数为奇数) )A是满足下述是满足下述条件:条件: 当当| i-j |(k-1)/2时,时, ai j=0 火氖驳遁哮碑抡南磁疡挝损慢弱以庆绎阁攻沼昼嚣稀渤荐蹬抢喉哆拽裙胃数据结构严蔚敏PPT数据结构严蔚敏PPT 对角矩阵可

241、按对角矩阵可按行优先顺序行优先顺序或或对角线顺序对角线顺序,将其压缩,将其压缩存储到一个向量中,并且也能找到每个非零元素和向量存储到一个向量中,并且也能找到每个非零元素和向量下标的对应关系。下标的对应关系。 仍然以三对角矩阵为例讨论。仍然以三对角矩阵为例讨论。当当i=1,j=1、2,或或i=n, j=n-1、n或或1in-1,j=i-1、i、i+1的元素的元素aij外,其余元素都是外,其余元素都是0。 对这种矩阵,当以按对这种矩阵,当以按“行优先顺序行优先顺序”存储时,存储时, 第第1行和第行和第n行是行是2个非零元素,其余每行的非零元素都要是个非零元素,其余每行的非零元素都要是3个,则需存储

242、的元素个数为个,则需存储的元素个数为3n-2。sa a11 a12 a21 a22 a23 a32 a33 a34 an n-1 annK 1 2 3 4 5 6 7 8 3n-3 3n-2图图5-7 三三对角矩阵的对角矩阵的压缩存储示例压缩存储示例痉悔聚害良英髓蔡涨躯莱挂桥妥豺遭籽怯淌厌施栈练灯茄荡熟寻扮丙余自数据结构严蔚敏PPT数据结构严蔚敏PPT 如图如图5-7所示所示三三对角矩阵的对角矩阵的压缩存储形式压缩存储形式。数组。数组sa中的元素中的元素sak与三对角矩阵中的元素与三对角矩阵中的元素aij存在一一对应关存在一一对应关系,在系,在aij之前有之前有i-1行行, ,共有共有3 i-

243、1个非零元素,在第个非零元素,在第i行,行,有有j-i+1个非零元素,这样,非零元素个非零元素,这样,非零元素aij的地址为:的地址为: LOCai j =LOCa11 +3 i-1+(j-i+1) l =LOCa11+(2 i+j) l上例中,上例中,a34对应着对应着sa10 , , k=2 i+j=2 3+4=10称称sa03 n-2是是n阶三对角矩阵阶三对角矩阵A的压缩存储。的压缩存储。 上述各种特殊矩阵,其非零元素的分布都是有规律上述各种特殊矩阵,其非零元素的分布都是有规律的,因此总能找到一种方法将它们压缩存储到一个向量的,因此总能找到一种方法将它们压缩存储到一个向量中,并且一般都能

244、找到矩阵中的元素与该向量的对应关中,并且一般都能找到矩阵中的元素与该向量的对应关系,通过这个关系,仍能对矩阵的元素进行随机存取。系,通过这个关系,仍能对矩阵的元素进行随机存取。 砍碑芬拖契季胡陈嚎滓蹄氨饲劈荔宵绰苑庚辅陷砷糜鸳枢讨躺亦否灵族翅数据结构严蔚敏PPT数据结构严蔚敏PPT5.3.2 稀疏矩阵稀疏矩阵稀疏矩阵稀疏矩阵(Sparse Matrix):对于稀疏矩阵,目前还对于稀疏矩阵,目前还没有一个确切的定义。设矩阵没有一个确切的定义。设矩阵A是一个是一个n m的的矩阵中有矩阵中有s个非零元素,设个非零元素,设 =s/(n m),称称为为稀疏因子,如果稀疏因子,如果某一矩阵的稀疏因子某一矩

245、阵的稀疏因子满足满足0.05时称为稀疏矩阵,如时称为稀疏矩阵,如图图5-8所示。所示。0 12 9 0 0 0 0 00 0 0 0 0 0 0 0-3 0 0 0 0 0 0 40 0 24 0 0 2 0 00 18 0 0 0 0 0 00 0 0 0 0 0 -7 0A=0 0 0 -6 0 0 0 0图图5-8 稀疏稀疏矩阵矩阵示例示例蠢铬瘪岛歹唯哺税锰煎兜哼枚猜潘常弃拾饥绊派蚂孰洒痘阂侣孽苍李想娃数据结构严蔚敏PPT数据结构严蔚敏PPT5.3.2.1 稀疏矩阵的压缩存储稀疏矩阵的压缩存储 对于稀疏矩阵,采用压缩存储方法时,只存储非对于稀疏矩阵,采用压缩存储方法时,只存储非0元素。必

246、须存储非元素。必须存储非0元素的行下标值、列下标值、元素元素的行下标值、列下标值、元素值。因此,一个三元组值。因此,一个三元组(i, j, aij)唯一确定稀疏矩阵的一唯一确定稀疏矩阵的一个非零元素。个非零元素。 如图如图5-8的稀疏矩阵的稀疏矩阵A的三元组线性表为:的三元组线性表为:( (1,2,12), (1,3,9), (3,1,-3), (3,8,4), (4,3,24), (5,2,18), (6,7,-7), (7,4,-6) ) 1 三元组顺序表三元组顺序表 若以行序为主序,稀疏矩阵中所有非若以行序为主序,稀疏矩阵中所有非0元素的三元组,元素的三元组,就可以得构成该稀疏矩阵的一个

247、三元组顺序表。就可以得构成该稀疏矩阵的一个三元组顺序表。墟墨妊盐料哥屯般森泛氛拼羚搓瘸版添左何嫁陵雏堕敦陪忿忍鹿肪损捆痈数据结构严蔚敏PPT数据结构严蔚敏PPT1 三元组顺序表三元组顺序表 若以行序为主序,稀疏矩阵中所有非若以行序为主序,稀疏矩阵中所有非0元素的三元元素的三元组,就可以得构成该稀疏矩阵的一个三元组顺序表。相组,就可以得构成该稀疏矩阵的一个三元组顺序表。相应的数据结构定义如下:应的数据结构定义如下: 三元组结点定义三元组结点定义 #define MAX_SIZE 101typedef int elemtype ;typedef struct int row ; /* 行下标行下标

248、 */int col ; /* 列下标列下标 */elemtype value; /* 元素值元素值 */Triple ;峦兵猫廉幸亚沦侧妊辊懊捶惧望型鼓语冕痰刺害雪搔献骸辊旋公眷氰酵搅数据结构严蔚敏PPT数据结构严蔚敏PPT 三元组顺序表定义三元组顺序表定义 typedef struct int rn ; /* 行数行数 */int cn ; /* 列数列数 */int tn ; /* 非非0元素个数元素个数 */Triple dataMAX_SIZE ; TMatrix ; 图图5-8所示的稀疏矩阵及其相应的转置矩阵所对应的所示的稀疏矩阵及其相应的转置矩阵所对应的三元组顺序表如图三元组顺序

249、表如图5-9所示。所示。 凰能疵张狸鳃牛燃瞻遂估砌桥谨闪挫拖斜漂卖柴盲炯强芳斜涎殆迂变保艇数据结构严蔚敏PPT数据结构严蔚敏PPT图图5-9 稀疏稀疏矩阵及其转置矩阵的三元组顺序表矩阵及其转置矩阵的三元组顺序表798rn行数行数cn列数列数tn元素个数元素个数row col value1 2 121 3 93 1 -33 8 44 3 245 2 186 7 -77 4 -64 6 2(a) 原原矩阵的三元组矩阵的三元组表表897rn行数行数cn列数列数tn元素个数元素个数row col value1 3 -32 1 122 5 183 1 93 4 244 7 -67 6 -78 2 46

250、4 2(b)转置矩阵的三元组表转置矩阵的三元组表暑袱干完遂兔已萍小土涅贝掘畸寸窑慈居灿磋皮命午衬辫预黄佩息事甸锁数据结构严蔚敏PPT数据结构严蔚敏PPT 矩阵的运算包括矩阵的转置、矩阵求逆、矩阵的加矩阵的运算包括矩阵的转置、矩阵求逆、矩阵的加减、矩阵的乘除等。在此,先讨论在这种压缩存储结构减、矩阵的乘除等。在此,先讨论在这种压缩存储结构下的求矩阵的转置的运算。下的求矩阵的转置的运算。 一个一个m n的矩阵的矩阵A,它的转置,它的转置B是一个是一个n m的矩的矩阵,且阵,且bij=aji,0in,0jm,即,即B的行是的行是A的列,的列,B的列是的列是A的行。的行。 设稀疏矩阵设稀疏矩阵A是是按

251、行优先顺序按行优先顺序压缩存储在三元组表压缩存储在三元组表a.data中,若仅仅是简单地交换中,若仅仅是简单地交换a.data中中i和和j的内容,得的内容,得到三元组表到三元组表b.data,b.data将是一个将是一个按列优先顺序按列优先顺序存储存储的稀疏矩阵的稀疏矩阵B,要得到按行优先顺序存储的,要得到按行优先顺序存储的b.data,就,就必须重新排列三元组表必须重新排列三元组表b.data中元素的顺序。中元素的顺序。咒荷怠负狱衔力邻析樟秧弯肄挺诣汝菊唉倪梗泡悼铅绘钎欠牙抄钟葡函垃数据结构严蔚敏PPT数据结构严蔚敏PPT 求转置矩阵的基本算法思想是:求转置矩阵的基本算法思想是: 将矩阵的行

252、将矩阵的行、列下标值交换。即将三元组表中的列下标值交换。即将三元组表中的行行、列位置值列位置值i 、j相互相互交换交换; 重排三元组表重排三元组表中元素中元素的顺序。即交换后仍然是的顺序。即交换后仍然是按按行优先顺序行优先顺序排序的。排序的。方法一方法一:算法思想算法思想:按稀疏矩阵按稀疏矩阵A的的三元组表三元组表a.data中的中的列次序列次序依次依次找到相应的三元组存入找到相应的三元组存入b.data中。中。 每找转置后矩阵的一个三元组,需从头至尾扫描整每找转置后矩阵的一个三元组,需从头至尾扫描整个三元组表个三元组表a.data 。找到之后自然就成为按行优先的转。找到之后自然就成为按行优先

253、的转置矩阵的压缩存储表示。置矩阵的压缩存储表示。荆掉蹦椽缩谐嗜挫尽庙访闸卖滁虫文耿种云坛胀弃孽略黎蹈守政超蜡划谤数据结构严蔚敏PPT数据结构严蔚敏PPT按方法一求转置矩阵的算法如下:按方法一求转置矩阵的算法如下:void TransMatrix(TMatrix a , TMatrix b) int p , q , col ;b.rn= ; =a.rn ; b.tn=a.tn ;/* 置置三元组表三元组表b.data的的行行、列数和非列数和非0元素个数元素个数 */if (b.tn=0) printf(“ The Matrix A=0n” );else q=0;for (col=1; col=

254、; col+) /* 每循环一次找到转置后的一个三元组每循环一次找到转置后的一个三元组 */for (p=0 ;pa.tn ; p+) /* 循环次数是非循环次数是非0元素个数元素个数 */瞪洲略狱技逾悬谜酪评妊剔阐渺衷屿纶些侦瞅爷漳谈帆沈烷青节探切波卒数据结构严蔚敏PPT数据结构严蔚敏PPT if (a.datap.col=col) b.dataq.row=a.datap.col ; b.dataq.col=a.datap.row ; b.dataq.value=a.datap.value; q+ ; 算法分析算法分析:本算法主要的工作是在本算法主要的工作是在p和和col的两个循环的两个循环

255、中完成的,故算法的时间复杂度为中完成的,故算法的时间复杂度为O(cn tn),即矩阵,即矩阵的列数和非的列数和非0元素的个数的乘积成正比。元素的个数的乘积成正比。咖钩镀熔菱滤瓶疹厦东鞋鸽淮据缸想冻踪剥址韩俭隔财捐外贼蘸疑扎秉框数据结构严蔚敏PPT数据结构严蔚敏PPT而一般传统矩阵的转置算法为:而一般传统矩阵的转置算法为:for(col=1; col=n ;+col)for(row=0 ; row=m ;+row)bcolrow=arowcol ; 其时间复杂度为其时间复杂度为O(n m)。当非零元素的个数。当非零元素的个数tn和和m n同数量级时,算法同数量级时,算法TransMatrix的时

256、间复杂度为的时间复杂度为O(m n2)。 由此可见,虽然节省了存储空间,但时间复杂度却由此可见,虽然节省了存储空间,但时间复杂度却大大增加。所以上述算法只适合于稀疏矩阵中非大大增加。所以上述算法只适合于稀疏矩阵中非0元素元素的个数的个数tn远远小于远远小于m n的情况的情况。余幻浇嘘励忆辛桥饵禾要一恒献尝富烫仔柔抱柱积钡滦蜒夕跳办稀窜亩膛数据结构严蔚敏PPT数据结构严蔚敏PPT方法二方法二( (快速转置的算法快速转置的算法) ) 算法思想算法思想:直接按照稀疏矩阵直接按照稀疏矩阵A的的三元组表三元组表a.data的的次次序依次顺序转换序依次顺序转换,并将转换后的三元组,并将转换后的三元组放置于

257、放置于三元组表三元组表b.data的的恰当位置恰当位置。 前提前提:若能预先确定原矩阵若能预先确定原矩阵A中每一列的中每一列的(即即B中中每一行每一行)第一个非第一个非0元素在元素在b.data中应有中应有的位置,则在作的位置,则在作转置时就可直接放在转置时就可直接放在b.data中恰当中恰当的位置。因此,应的位置。因此,应先先求得求得A中每一列的非中每一列的非0元素个数元素个数。附设两个辅助向量附设两个辅助向量num 和和cpot 。 numcol:统计:统计A中第中第col列中非列中非0元素的个数元素的个数; cpotcol :指示:指示A中第一个非中第一个非0元素在元素在b.data中的

258、中的恰当恰当位置。位置。妥卓茎贤粘啮恤亥够驼腐脐虏唾魄棋辊菏脯峨涂敌扩遵围慷卯吨暗颖汲友数据结构严蔚敏PPT数据结构严蔚敏PPT显然有位置对应关系:显然有位置对应关系:cpot1=1cpotcol=cpotcol-1+numcol-1 例图例图5-8中的矩阵中的矩阵A和表和表5-9(a)的的相应的三元组表可相应的三元组表可以求得以求得numcol和和cpotcol的值如表的值如表5-1:numcol 1 2 2 1 0 1 1 1 col 1 2 3 4 5 6 7 8cpotcol 1 3 5 6 6 7 8 9表表5-1 numcol和和cpotcol的值表的值表申缩伸勋爹氧抱韭凤研翱供

259、歪痢裹糜磊臆扩基够凑己霹乙姿脚目咆儿绢爷数据结构严蔚敏PPT数据结构严蔚敏PPT快速转置算法如下:快速转置算法如下: void FastTransMatrix(TMatrix a, TMatrix b) int p , q , col , k ;int numMAX_SIZE , coptMAX_SIZE ;b.rn= ; =a.rn ; b.tn=a.tn ; /* 置置三元组表三元组表b.data的的行行、列数和非列数和非0元素个数元素个数 */ if (b.tn=0) printf(“ The Matrix A=0n” ) ;else for (col=1 ; col= ; +col)

260、numcol=0 ; /* 向量向量num初始化为初始化为0 */ for (k=1 ; k=a.tn ; +k) +num a.datak.col ; /* 求原求原矩阵中每一列非矩阵中每一列非0元素个数元素个数 */录氯稿摘契哄膏翁敌躲住筏从稠钥侨历矗檄同求运搓打秀序拾妒词歼森范数据结构严蔚敏PPT数据结构严蔚敏PPTfor (cpot0=1, col=2 ; col= ; +col) cpotcol=cpotcol-1+numcol-1 ; /* 求第求第col列中第一个非列中第一个非0元在元在b.data中的序号中的序号 */for (p=1 ; p=a.tn ; +p) col=a.

261、datap.col ; q=cpotcol ; b.dataq.row=a.datap.col ; b.dataq.col=a.datap.row ; b.dataq.value=a.datap.value ; +cpotcol ; /*至关重要至关重要!当本当本列中列中 */ 捡脊晴盛危但崇钥恋壮匿透线月笑盟蒜倒嘛户彪齿饱韭宁谷谍藤揣脉呀蜂数据结构严蔚敏PPT数据结构严蔚敏PPT2 行逻辑链接的三元组顺序表行逻辑链接的三元组顺序表 将上述方法二中的辅助向量将上述方法二中的辅助向量cpot 固定在稀疏矩阵固定在稀疏矩阵的三元组表中,用来指示的三元组表中,用来指示“行行”的信息。得到另一种顺的信

262、息。得到另一种顺序存储结构:序存储结构:行逻辑链接的三元组顺序表行逻辑链接的三元组顺序表。其类型描述。其类型描述如下:如下:#define MAX_ROW 100typedef struct Triple dataMAX_SIZE ; /* 非非0元素的三元组表元素的三元组表 */ int rposMAX_ROW; /* 各行第一个非各行第一个非0位置表位置表 */ int rn ,cn , tn ; /* 矩阵的行、列数和非矩阵的行、列数和非0元个数元个数 */RLSMatrix ;培榔冗屹征跺泉哥贾杨笑笺紫灯灸规悄陈甥婉弟么悬住义裙履游俱廓奶乖数据结构严蔚敏PPT数据结构严蔚敏PPT稀疏矩

263、阵的乘法稀疏矩阵的乘法设有两个矩阵:设有两个矩阵:A=(aij)m n ,B=(bij)n p则:则: C=(cij)m p 其中其中 cij=aik bkj 1kn , 1im ,1jp经典算法是三重循环:经典算法是三重循环:for ( i=1 ; i=m ; +i)for ( j=1 ; j=p ; +j) cij=0 ;for ( k=1 ; k=n ; +k) cij= cij+aik bkj;此算法的复杂度为此算法的复杂度为O(m n p)。饲蹈榜戳妖瞬偏英女泡锡坏觅镑戚洁砾徘彦座裙镣算苑衅泼宰镶钓吻掖喜数据结构严蔚敏PPT数据结构严蔚敏PPT 设有两个稀疏矩阵设有两个稀疏矩阵A=(

264、aij)m n ,B=(bij)n p ,其,其存储存储结构采用行逻辑链接的三元组顺序表。结构采用行逻辑链接的三元组顺序表。算法思想算法思想:对于对于A中的每个元素中的每个元素a.datap(p=1, 2, , a.tn),找到,找到B中所有满足条件:中所有满足条件: a.datap.col=b.dataq.row的元素的元素b.dataq,求得求得a.datap.value b.dataq.value,该乘积是,该乘积是cij中的一部中的一部分。求得所有这样的乘积并累加求和就能得到分。求得所有这样的乘积并累加求和就能得到cij。 为得到非为得到非0 0的乘积的乘积,只要,只要对对a.data

265、1a.tn 中每个元中每个元素素(i,k,aik)(1ia.rn,) ,找到找到b.data中所有相应的元素中所有相应的元素(k,j,bkj)(1kb.rn,) 相乘即可相乘即可。则。则必须知道必须知道矩阵矩阵B中第中第k行的所行的所有非有非0元素,而元素,而b.rpos 向量中提供了相应的信息向量中提供了相应的信息。伞羡峭俄翟毙彭抨髓朝滁晤讹圾重灯赂燕约柿圭姑藕悼傀泰摧催国妈贩言数据结构严蔚敏PPT数据结构严蔚敏PPT b.rposrow指示了指示了矩阵矩阵B的第的第row行中第一个非行中第一个非0元元素在素在b.data 中的位置中的位置(序号序号),显然,显然,b.rposrow+1-1

266、指示了第指示了第row行中最后一个非行中最后一个非0元素在元素在b.data 中的位置中的位置(序号序号) 。最后一。最后一行中最后一个非行中最后一个非0元素在元素在b.data 中的中的位置显然就是位置显然就是b.tn 。两个稀疏矩阵相乘的两个稀疏矩阵相乘的算法如下:算法如下:void MultsMatrix(RLSMatrix a, RLSMatrix b, RLSMatrix c) /* 求求矩阵矩阵A 、B的积的积C=A B,采用行逻辑链接的顺序表采用行逻辑链接的顺序表 */ */ elemtype ctempMax_Size ;int p , q , arow , ccol , br

267、ow , t ; if (!=b.rn) printf(“Errorn”) ; exit(0); 枯苯嘴遗寸绽推霍他劈姚活蛋聋阳洱余瞩桂揭道桌惕择酥扯梭肆镜俄吏频数据结构严蔚敏PPT数据结构严蔚敏PPTelse c.rn=a.rn ; =b. n ; c.tn=0 ; /* 初始化初始化C */if (a.tn*b.tn!=0) /* C 是非零矩阵是非零矩阵 */ for (arow=1 ; arow=a.rn ; +arow) ctemparow=0 ; /* 当前行累加器清零当前行累加器清零 */ c.rposarow=c.tn+1; p=a.ropsarow; for ( ; pa.r

268、posarow+1;+p) /* 对第对第arow行的每一个非行的每一个非0元素元素 */ brow=a.datap.col ; /* 找到元素在找到元素在b.data中的行号中的行号 */ if () t=( b.rposbrow+1; else t=b.tn+1 ; 腮璃滥曙娶延厨茨棺桓绪虎棕拧艘锤舞伍今良苑冗碑喝撮骑蔷类扇搽艳旦数据结构严蔚敏PPT数据结构严蔚敏PPT for (q=b.rposbrow ; qt ; +q) ccol=b.dataq.col ; /* 积元素在积元素在c中的列号中的列号 */ ctempccol+=a.datap.value*b.dataq.value

269、; /* 求出求出c中第中第arow行中的非行中的非0元素元素 */for (ccol=1 ; ccolMAX_SIZE) printf(“Errorn”) ; exit(0); else宰尉防才二街架竹粳峪只伤晶钓宪赂囱翁菌归滩速诸劲恋零未弟湛肢府且数据结构严蔚敏PPT数据结构严蔚敏PPTc.datac.tn=(arow , ccol , ctempccol) ; 农蚂倚们蝇搁钎靡太轮锋悯凯钮撰浦钳搀局爹停休琢濒焉廓刷诫戎梨浊篱数据结构严蔚敏PPT数据结构严蔚敏PPT3 十字链表十字链表 对于稀疏矩阵,当非对于稀疏矩阵,当非0元素的个数和位置在操作过元素的个数和位置在操作过程中变化较大时,采

270、用链式存储结构表示比三元组的线程中变化较大时,采用链式存储结构表示比三元组的线性表更方便。性表更方便。 矩阵中非矩阵中非0元素的结点所含的域有:元素的结点所含的域有:行行、列列、值值、行指针行指针(指向同一行的下一个非指向同一行的下一个非0元元)、列指针列指针(指向同一指向同一列的下一个非列的下一个非0元元)。其次,十字交叉链表还有一个头结。其次,十字交叉链表还有一个头结点,结点的结构如图点,结点的结构如图5-10所示。所示。图图5-10 十字链十字链表结点结构表结点结构row col value down right rn cn tn down right(a) 结点结构结点结构(b) 头头

271、结点结结点结构构戚肥字董忠驯震寓齿分烫又泻浑肚旨去陈坟愿汉弹钒诣势衫柜博唾射济滓数据结构严蔚敏PPT数据结构严蔚敏PPT 由定义知,稀疏矩阵中同一行的非由定义知,稀疏矩阵中同一行的非0元素的由元素的由right指针域链接成一个行链表指针域链接成一个行链表, 由由down指针域链接成一个指针域链接成一个列链表列链表。则每个非。则每个非0元素既是元素既是某个行链表中的一个结点某个行链表中的一个结点,同时又同时又是是某个列链表中的一个结点某个列链表中的一个结点,所有的,所有的非非0元素元素构构成一个成一个十字交叉十字交叉的链表。称为的链表。称为十字链表十字链表。 此外,还可用两个此外,还可用两个一一

272、维数组分别存储行维数组分别存储行链表的头指链表的头指针和列链表的头指针针和列链表的头指针。对于图。对于图5-11(a)的的稀疏矩阵稀疏矩阵A ,对,对应的十字交叉链表如图应的十字交叉链表如图5-11(b)所示,结点的描述如下:所示,结点的描述如下:typedef struct Clnode int row , col ; /* 行号和列号行号和列号 */ elemtype value ; /* 元素值元素值 */struct Clnode *down , *right ;OLNode ; /* 非非0元素结点元素结点 */圃企握研旺际芥哭垦电诬茬座蓉植蒸蛔擒渠转骗羌期巍更茧苟削妙予崭旁数据结构

273、严蔚敏PPT数据结构严蔚敏PPTtypedef struct Clnode int rn; /* 矩阵的矩阵的行数行数 */ int cn; /* 矩阵的矩阵的列数列数 */int tn; /* 非非0元素总数元素总数 */OLNode *rhead ; OLNode *chead ; CrossList ;图图5-11 稀疏稀疏矩阵矩阵及其及其十字交叉链表十字交叉链表0 12 0 0 00 0 0 0 -40 5 0 0 00 0 3 0 0A=(a) 稀疏稀疏矩阵矩阵(b(b) 稀疏稀疏矩阵的十字交叉链表矩阵的十字交叉链表A.cheadA.rchead 1 2 12 3 2 5 2 5 -

274、4 4 3 3 扒剁佃财膜粉遍访官魁噎圣相堕捶犊钎划垄宜憎怀卑愉裳牧艺梭为滞然换数据结构严蔚敏PPT数据结构严蔚敏PPT5.4 广义表广义表 广义表是线性表的推广和扩充,在人工智能领域广义表是线性表的推广和扩充,在人工智能领域中应用十分广泛。中应用十分广泛。 在第在第2章中,我们把线性表定义为章中,我们把线性表定义为n(n0 )个元素个元素a1, a2 , an的有穷序列,该序列中的所有元素具有相同的的有穷序列,该序列中的所有元素具有相同的数据类型且只能是原子项数据类型且只能是原子项(Atom)。所谓。所谓原子项可以是一原子项可以是一个数或一个结构,是指结构上不可再分的个数或一个结构,是指结构

275、上不可再分的。若放松对元。若放松对元素的这种限制,容许它们具有其自身结构,就产生了广素的这种限制,容许它们具有其自身结构,就产生了广义表的概念。义表的概念。 广义表广义表(Lists,又称为列表又称为列表 ):是由是由n(n 0)个个元素组成的有穷序列:元素组成的有穷序列: LS=(a1,a2,an)域炳氓远枉躇姨败仙蹲添拢酒柯才役叁急呆棺燃曲面凹尘税典痞愧嫂收堵数据结构严蔚敏PPT数据结构严蔚敏PPT其中其中ai或者是原子项,或者是一个广义表。或者是原子项,或者是一个广义表。LS是广义是广义表的名字,表的名字,n为它的长度。若为它的长度。若ai是广义表,则称为是广义表,则称为LS的子表。的子

276、表。习惯上:原子用习惯上:原子用小写字母小写字母,子表用,子表用大写字母大写字母。若广义表若广义表LS非空时:非空时: a1(表中第一个元素表中第一个元素)称为称为表头表头; 其余元素组成的子表称为其余元素组成的子表称为表尾表尾;(a2,a3,an) 广义表中所包含的元素广义表中所包含的元素(包括原子和子表包括原子和子表)的个数的个数称为表的长称为表的长 度。度。 广义表中括号的最大层数称为表深广义表中括号的最大层数称为表深 (度度)。有关广义表的这些概念的例子如表有关广义表的这些概念的例子如表5-2所示。所示。菜简殿孽缸灼感袍开虹锑闽拦潍涵豫捣窑喇逗嘘终彤仰隆陶蝗逝秩馏财骚数据结构严蔚敏PP

277、T数据结构严蔚敏PPT表表5-2 广义广义表及其示例表及其示例广广 义义 表表表长表长n 表深表深hA=()00B=(e)11C=(a,(b,c,d)22D=(A,B,C)33E=(a,E)2F=()12abecdABCD图图5-12 广义广义表的图形表示表的图形表示束积裳付铸征跳痘礼晒烂毋俏猖毯钙吊禹疡机贤染缅耍喊麓文杉坟慨炼培数据结构严蔚敏PPT数据结构严蔚敏PPT广义表的重要结论广义表的重要结论: 广义表的元素可以是原子,也可以是子表,子表广义表的元素可以是原子,也可以是子表,子表的元素又可以是子表,的元素又可以是子表, 。即即广义表是一个多层次广义表是一个多层次的结构。的结构。 表表5

278、-2中的中的广义表广义表D的图形表示如图的图形表示如图5 5-12所示所示。(2) (2) 广义表可以被其它广义表广义表可以被其它广义表所共享所共享,也可以,也可以共享共享其其它广义表。广义表它广义表。广义表共享共享其它广义表时通过表名引用。其它广义表时通过表名引用。(3) (3) 广义表本身可以是一个递归表。广义表本身可以是一个递归表。(4) (4) 根据对根据对表头、表尾表头、表尾的定义,任何一个非空广义表的定义,任何一个非空广义表的的表头表头可以是原子,也可以是子表,可以是原子,也可以是子表, 而表尾而表尾必定是必定是广义表。广义表。显项甭琳漆满问跪啸陀玄砷官筛颅恼狰砒振尊王骚遭沛疽脚摸

279、谊浴剖滩呈数据结构严蔚敏PPT数据结构严蔚敏PPT5.4.1 广义表的存储结构广义表的存储结构 由于广义表中的数据元素具有不同的结构,通常由于广义表中的数据元素具有不同的结构,通常用链式存储结构用链式存储结构表示,每个数据元素用一个结点表示。表示,每个数据元素用一个结点表示。因此,广义表中就有两类结点:因此,广义表中就有两类结点: 一类是一类是表结点表结点,用来表示广义表项,由标志域,用来表示广义表项,由标志域,表头指针域,表尾指针域组成表头指针域,表尾指针域组成; 另一类是另一类是原子原子结点结点,用来表示原子项,由标志域,用来表示原子项,由标志域,原子的值域组成。原子的值域组成。如图如图5

280、-13所示所示。 只要广义表非空,都是由只要广义表非空,都是由表头和表尾组成表头和表尾组成。即一个。即一个确定的确定的表头和表尾就唯一确定一个表头和表尾就唯一确定一个广义表。广义表。饿帮越扎拆绪菊以蝉峪犀锄茬谤辉吩谐轧算效扰捷幅缆担款化丧靴伟稽市数据结构严蔚敏PPT数据结构严蔚敏PPT相应的数据结构定义如下:相应的数据结构定义如下:typedef struct GLNode int tag ; /* 标志域,为标志域,为1:表结点:表结点; ;为为0 :原子结点:原子结点 */union elemtype value; /* 原子结点的原子结点的值域值域 */struct struct GLN

281、ode *hp , *tp ; ptr ; /* ptr和和atom两成员共用两成员共用 */Gdata ; GLNode ; /* 广义表广义表结点类型结点类型 */标志标志tag=0 原子的原子的值值 标志标志tag=1 表头指针表头指针hp 表尾指针表尾指针tp 图图5-13 广义广义表的链表结点结构示意图表的链表结点结构示意图(b) 表结点表结点(a) 原子结点原子结点使窗鼠衣愁记鲜维睫泄堵馆岂掇者限填昨懈撕盯屯讯蛊狠衍肚浇巴褥坛廊数据结构严蔚敏PPT数据结构严蔚敏PPT例例: 对对A=(),B=(e),C=(a, (b, c, d) ),D=(A, B, C),E=(a, E)的广义

282、表的存储结构的广义表的存储结构如图如图5 5-14所示所示。A=NULL1 0 eB10 aC10 b1 10 c1 0 dD1 1 11 10 aE1 图图5-14 广义广义表的存储结构示意图表的存储结构示意图边它埋绩钟朝乳锌乳考旬媒绵月婶汽瓤帘藕杖借售疾朔驶幅鞋酋放藐柱璃数据结构严蔚敏PPT数据结构严蔚敏PPT对于上述对于上述存储结构,有如下几个特点:存储结构,有如下几个特点:(1) 若广义表为空,表头指针为空若广义表为空,表头指针为空;否则否则,表头指针,表头指针总是指向一个表结点,其中总是指向一个表结点,其中hp指向广义表的表头结点指向广义表的表头结点( (或为原子结点,或为表结点或为

283、原子结点,或为表结点) ) ,tp指向广义表的表指向广义表的表尾尾( (表尾为空时,指针为空,否则必为表结点表尾为空时,指针为空,否则必为表结点) )。(2) 这种结构求这种结构求广义表的长度广义表的长度、深度深度、表头表头、表尾的表尾的操作十分方便。操作十分方便。(3) 表结点太多表结点太多,造成空间浪费造成空间浪费。也可用。也可用图图5 5-15所示所示的结点结构的结点结构。图图5-15 广义广义表的链表结点结构示意图表的链表结点结构示意图(b) 表结点表结点(a) 原子结点原子结点tag=1 表头指针表头指针hp 表尾指针表尾指针tp tag=0 原子的原子的值值 表尾指针表尾指针tp

284、赚呕杰侠邀支民谆综寺腾滴鸵篆席缕钾刹善预民瘩堆揽莱屑酣灸爪彭赊漆数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 五五 什么是广义表?请简述广义表与线性表的区别?什么是广义表?请简述广义表与线性表的区别? 一个广义表是一个广义表是(a, (a, b), d, e, (a, (i, j), k) ,请画,请画出该广义表的链式存储结构。出该广义表的链式存储结构。 设有二维数组设有二维数组a68,每个元素占相邻的,每个元素占相邻的4个字个字节,存储器按字节编址,已知节,存储器按字节编址,已知a的起始地址是的起始地址是1000,试,试计算:计算: 数组数组a的最后一个元素的最后一个元素a57起始地址

285、;起始地址; 按行序优先时,元素按行序优先时,元素a46起始地址;起始地址; 按行序优先时,元素按行序优先时,元素a46起始地址。起始地址。恼汪鸽首无羽没嫉脆拓桨捣负钢药匡簧沮斡蹿诺刨芬逾涂帖渣嚼佬戍签踢数据结构严蔚敏PPT数据结构严蔚敏PPT0 3 0 0 0 0 0 00 0 0 0 0 0 0 0-3 0 0 0 0 0 0 40 0 2 0 0 2 0 00 18 0 0 0 0 0 00 0 0 0 4 0 5 0A=0 0 -3 0 0 0 0 0 设设A和和B是稀疏矩阵,都以三元组作为存储结构,是稀疏矩阵,都以三元组作为存储结构,请写出矩阵相加的算法,其结果存放在三元组表请写出矩

286、阵相加的算法,其结果存放在三元组表C中,中,并分析时间复杂度。并分析时间复杂度。 设有稀疏矩阵设有稀疏矩阵B如下图所示,请画出该稀疏矩阵如下图所示,请画出该稀疏矩阵的三元组表和十字链表存储结构。的三元组表和十字链表存储结构。亥痞珍林片铂捎扁啃岩渴钥常饭野吧抿蒋猪危迎侩源梭曼浓撼豁刀嘱挪似数据结构严蔚敏PPT数据结构严蔚敏PPT第第6章章 树和二叉树树和二叉树 树型结构是一类非常重要的非线性结构。直观地,树型结构是一类非常重要的非线性结构。直观地,树型结构是树型结构是以分支关系定义的层次结构以分支关系定义的层次结构。 树在计算机领域中也有着广泛的应用,例如在编译树在计算机领域中也有着广泛的应用,

287、例如在编译程序中,用树来表示源程序的语法结构;在数据库系统程序中,用树来表示源程序的语法结构;在数据库系统中,可用树来组织信息;在分析算法的行为时,可用树中,可用树来组织信息;在分析算法的行为时,可用树来描述其执行过程等等。来描述其执行过程等等。 本章将详细讨论树和二叉树数据结构,主要介绍树本章将详细讨论树和二叉树数据结构,主要介绍树和二叉树的概念、术语,二叉树的遍历算法。树和二叉和二叉树的概念、术语,二叉树的遍历算法。树和二叉树的各种存储结构以及建立在各种存储结构上的操作及树的各种存储结构以及建立在各种存储结构上的操作及应用等。应用等。篡砷肤套挽筛爆吏季絮腮督且辨荫拟窿思区酥狐教牛稀学堑侩习

288、驴愤引腆数据结构严蔚敏PPT数据结构严蔚敏PPT6.1 树的基本概念树的基本概念1 树的定义树的定义 树树(Tree)是是n(n0)个结点的有限集合个结点的有限集合T,若,若n=0时时称为空树,否则:称为空树,否则: 有且只有一个特殊的称为树的根有且只有一个特殊的称为树的根(Root)结点;结点; 若若n1时,其余的结点被分为时,其余的结点被分为m(m0)个个互不相交互不相交的子集的子集T1, T2, T3Tm,其中每个子集本身又是一棵,其中每个子集本身又是一棵树,称其为根的子树树,称其为根的子树(Subtree)。 这是树的递归定义,即用树来定义树,而只有一个这是树的递归定义,即用树来定义树

289、,而只有一个结点的树必定仅由根组成,如图结点的树必定仅由根组成,如图6-1(a)所示。所示。 6.1.1 树的定义和基本术语树的定义和基本术语机肖莲计榷奢茹握危躁患驾敢压停毯核顿告沏尾钱懂奇欺灶铲取砂绪护守数据结构严蔚敏PPT数据结构严蔚敏PPT2 树的基本术语树的基本术语 结点结点(node):一个数据元素及其若干指向其子一个数据元素及其若干指向其子树的分支。树的分支。 结点的度结点的度(degree) 、树的度树的度:结点所拥有的结点所拥有的子树的棵数称为子树的棵数称为结点的度结点的度。树中结点度的最大值称为。树中结点度的最大值称为树的度树的度。 图图6-1 树的示树的示例形式例形式AAB

290、DCEGFHIMJNKL(a) 只有根结点只有根结点(b) 一般的树一般的树哪慨暖健鲁癌税猫知爽呆肪爷芝暂铃毗砷吻非货倔孕继绥植接密阀慌芳愁数据结构严蔚敏PPT数据结构严蔚敏PPT 如图如图6-1(b)中结点中结点A的度是的度是3 ,结点,结点B的度是的度是2 ,结点,结点M的度是的度是0,树的度是,树的度是3 。 叶子叶子(left)结点结点、非叶子结点非叶子结点:树中树中度为度为0的的结点称为结点称为叶子结点叶子结点( (或终端结点或终端结点) )。相对应地,。相对应地,度不度不为为0的的结点称为结点称为非叶子结点非叶子结点(或非终端结点或分支结点或非终端结点或分支结点) )。除根结点外,

291、分支结点又称为内部结点。除根结点外,分支结点又称为内部结点。 如图如图6-1(b)中结点中结点H、I、J、K、L、M、N是叶子是叶子结点,而所有其它结点都是分支结点。结点,而所有其它结点都是分支结点。 孩子结点孩子结点、双亲结点双亲结点、兄弟结点兄弟结点 一个结点的一个结点的子树的根子树的根称为该结点的孩子结点称为该结点的孩子结点(child)或子结点或子结点;相应地,该结点是其孩子结点的双相应地,该结点是其孩子结点的双亲结点亲结点(parent)或父结点。或父结点。位柒配秸蛹训趴苛严景烁傀摹青挫羹杏摧折整榔互坦瘩所柒征敌诱队缔俩数据结构严蔚敏PPT数据结构严蔚敏PPT 如图如图6-1(b)中

292、结点中结点B 、C、D是结点是结点A的子结点的子结点,而,而结点结点A是是结点结点B 、C、D的的父结点父结点;类似地结点类似地结点E 、F是是结点结点B的子结点的子结点,结点,结点B是是结点结点E 、F的的父结点。父结点。同一双亲结点的所有子结点互称为同一双亲结点的所有子结点互称为兄弟结点兄弟结点。 如图如图6-1(b)中结点中结点B 、C、D是兄弟结点;结点是兄弟结点;结点E 、F是兄弟结点。是兄弟结点。 层次层次、堂兄弟结点堂兄弟结点 规定树中根结点的层次为规定树中根结点的层次为1,其余结点的层次等于,其余结点的层次等于其双亲结点的层次加其双亲结点的层次加1。 若某结点在第若某结点在第l

293、(l1)层,则其子结点在第层,则其子结点在第l+1层。层。 双亲结点在同一层上的所有结点互称为双亲结点在同一层上的所有结点互称为堂兄弟结点堂兄弟结点。如图如图6-1(b)中结点中结点E、F、G、H、I、J。仇俐哥赖魄图掷还渝装盒掺口湍屡验植竹耀束爬笛娥耪忽善屎阎弦琴埃伪数据结构严蔚敏PPT数据结构严蔚敏PPT 结点的层次路径结点的层次路径、祖先祖先、子孙子孙 从根结点开始,到达某结点从根结点开始,到达某结点p所经过的所有结点成所经过的所有结点成为为结点结点p的的层次路径层次路径( (有且只有一条有且只有一条) )。 结点结点p的层次路径上的所有结点(的层次路径上的所有结点(p除外)称为除外)称

294、为p的的祖先祖先(ancester) 。 以某一结点为根的子树中的任意结点称为该结点的以某一结点为根的子树中的任意结点称为该结点的子孙结点子孙结点(descent)。 树的深度树的深度(depth):树中结点的最大层次值,又树中结点的最大层次值,又称为树的高度,如图称为树的高度,如图6-1(b)中树的高度为中树的高度为4。 有序树和无序树有序树和无序树:对于一棵树,若其中每一个对于一棵树,若其中每一个结点的子树(若有)具有一定的次序,则该树称为结点的子树(若有)具有一定的次序,则该树称为有有序树序树,否则称为,否则称为无序树无序树。屈疥旧离钵慎吭淘膊从紊瘁狡忱摩匝弃粘溺凤酿甲慎范啸念远蜡肄咙晶

295、虎数据结构严蔚敏PPT数据结构严蔚敏PPT 森林森林(forest):是是m(m0)棵互不相交的棵互不相交的树的树的集合。显然,若将一棵树的根结点删除,剩余的子树集合。显然,若将一棵树的根结点删除,剩余的子树就构成了森林。就构成了森林。3 树的表示形式树的表示形式 倒悬树倒悬树。是最常用的表示形式,如图是最常用的表示形式,如图6-1(b)。 嵌套集合嵌套集合。是一些集合的集体,对于任何两个集是一些集合的集体,对于任何两个集合,或者不相交,或者一个集合包含另一个集合。图合,或者不相交,或者一个集合包含另一个集合。图6-2(a)是图是图6-1(b)树的嵌套集合形式。树的嵌套集合形式。 广义表形式广

296、义表形式。图图6-2(b)是树的广义表形式。是树的广义表形式。 凹入法表示形式凹入法表示形式。见见P120 树的表示方法的多样化说明了树结构的重要性。树的表示方法的多样化说明了树结构的重要性。冬饺妊笨坠宾从踩葛奶弄攘抨今嫉蒙平裂崎冉俺熊沸本龋涡祈氓摹宇侗伴数据结构严蔚敏PPT数据结构严蔚敏PPT图图6-2 树的表示树的表示形式形式(a) 嵌套集合嵌套集合形式形式(b) 广义表广义表形式形式(A(B(E(K,L),F),C(G(M,N),D(H,I,J)HIJDFBKLECM NGA腺届从焉沟晾稽担停夯曼隅心爸与碉伐沿斗抚防豪井嫌因钞枣柬特揍呕剖数据结构严蔚敏PPT数据结构严蔚敏PPT6.1.2

297、 树的抽象数据类型定义树的抽象数据类型定义ADT Tree数据对象数据对象D:D是具有相同数据类型的数据元素的集是具有相同数据类型的数据元素的集合合。数据关系数据关系R:若:若D为空集为空集,则称为空树则称为空树; 基本操作:基本操作: ADT Tree 详见详见p118119。弛抖嫡蚁谐船淘苦忍挞听允廷抑合捧巷硅籽澜渍戒刹幢附揣朴瞳虽矛思咕数据结构严蔚敏PPT数据结构严蔚敏PPT6.2 二叉树二叉树6.2.1 二叉树的定义二叉树的定义1 二叉树的定义二叉树的定义 二叉树二叉树(Binary tree)是是n(n0)个结点的有限集合。个结点的有限集合。若若n=0时称为空树,否则:时称为空树,否

298、则: 有且只有一个特殊的称为树的根有且只有一个特殊的称为树的根(Root)结点;结点; 若若n1时,其余的结点被分成为时,其余的结点被分成为二个互不相交二个互不相交的子的子集集T1,T2,分别称之为左,分别称之为左、右子树,并且左右子树,并且左、右子树右子树又都是二叉树。又都是二叉树。 由此可知,二叉树的由此可知,二叉树的定义是递归定义是递归的。的。蚀掘价甩睬矮纱性葬军刻挤超彻不茹荆踩逊易圈鞍嫩挛赠浮展詹荧喜湃族数据结构严蔚敏PPT数据结构严蔚敏PPT 二叉树在树结构中起着非常重要的作用。因为二叉二叉树在树结构中起着非常重要的作用。因为二叉树结构简单,存储效率高,树的操作算法相对简单,且树结构

299、简单,存储效率高,树的操作算法相对简单,且任何树都很容易转化成二叉树结构。上节中引入的有关任何树都很容易转化成二叉树结构。上节中引入的有关树的术语也都适用于二叉树。树的术语也都适用于二叉树。2 二叉树的基本形态二叉树的基本形态 二叉树有二叉树有5种基本形态,如图种基本形态,如图6-3所示。所示。AAAA(a)(b)(c)(d)(e)(a) 空空二叉树二叉树(b) 单结点单结点二叉树二叉树(c) 右子树为空右子树为空(d) 左子树为空左子树为空(e) 左左、右子树都不空右子树都不空图图6-3 二叉二叉树的基本树的基本形态形态暇污蹬踢嘘揪炉掏守将操溪丑佩锣辈哺镜茵揭乖樊咱湾拷批掺瞬呸殴引樊数据结构

300、严蔚敏PPT数据结构严蔚敏PPT6.2.2 二叉树的性质二叉树的性质性质性质1:在非空二叉树中,第在非空二叉树中,第i i层上至多有层上至多有2i-1个结点个结点(i1)。证明证明:用数学归纳法证明。用数学归纳法证明。 当当i=1时:只有一个根结点,时:只有一个根结点,21-1=20 =1,命题成立。,命题成立。 现假设对现假设对i1时,处在第时,处在第i-1层上至多有层上至多有2(i-1)-1个结点。个结点。 由归纳假设知,第由归纳假设知,第i-1层上至多有层上至多有2i-2个结点。由于二个结点。由于二叉树每个结点的度最大为叉树每个结点的度最大为2,故在第,故在第i i层上最大结点数为层上最

301、大结点数为第第i-1层上最大结点数的层上最大结点数的2倍。倍。 即即 22i-22i-1 证毕证毕性质性质2:深度为深度为k的二叉树至多有的二叉树至多有2k-1个结点个结点(k1) 。捅勾闲琼侯右淋匪奠桨胆幢撇说花矢兢垮恳挣啼谈氨熙漏郸胜总钵寿心谋数据结构严蔚敏PPT数据结构严蔚敏PPT证明证明:深度为深度为k的二叉树的最大的结点数为二叉树中每的二叉树的最大的结点数为二叉树中每层上的最大结点数之和。层上的最大结点数之和。 由性质由性质1知知,二叉树的第,二叉树的第1层层、第第2层层 第第k层上的结层上的结点数至多有:点数至多有: 20、21 2k-1 。 总的总的结点数至多有:结点数至多有:

302、20+21+ + +2k-1=2k-1 证毕证毕 性质性质3:对任何一棵二叉树,若其叶子结点数为对任何一棵二叉树,若其叶子结点数为n0,度为度为2的结点数为的结点数为n2,则,则n0=n2+1。证明:证明:设二叉树中度为设二叉树中度为1的结点数为的结点数为n1,二叉树中总结,二叉树中总结点数为点数为N,因为二叉树中所有结点均小于或等于,因为二叉树中所有结点均小于或等于2,则有:,则有:N=n0+n1+n2再看二叉树中的分支数:再看二叉树中的分支数:帝杜雇迟疑律狂赌离未折蔷卞式伊忱芬磁懊数耙范侵怀雍罚冉挂瘪拘虚托数据结构严蔚敏PPT数据结构严蔚敏PPT 除根结点外,其余每个结点都有唯一的一个进入

303、分除根结点外,其余每个结点都有唯一的一个进入分支,而所有这些分支都是由度为支,而所有这些分支都是由度为1和和2的结点射出的。设的结点射出的。设B为二叉树中的分支总数,则有:为二叉树中的分支总数,则有: N=B+1 Bn1+2 n2 N=B+1=n1+2 n2+1 n0+n1+n2=n1+2 n2+1 即即 n0=n2+1 证毕证毕满二叉树和完全二叉树满二叉树和完全二叉树 一棵深度为一棵深度为k且有且有2k-1个结点的二叉树称为个结点的二叉树称为满二叉满二叉树树(Full Binary Tree)。 如图如图6-4(a) 就是一棵深度为就是一棵深度为4的满二叉树。的满二叉树。浆柜侮喀甸溉烂屯镣蕾

304、顶挑蛔井隘贩镶犹缴莲蝇羽挫催呆怖经郊懒票炼秉数据结构严蔚敏PPT数据结构严蔚敏PPT894101151213614157213894101152112673(a) 满二叉树满二叉树(b) 完全二叉树完全二叉树1362455674213(c) 非完全二叉树非完全二叉树图图6-4 特殊形态的特殊形态的二叉二叉树树躯儒霉耽凹胎厄舷箩艾绸舆矩颤液诉厨寒纺否庭姬粱翟僻替给义锄爵赴电数据结构严蔚敏PPT数据结构严蔚敏PPT满二叉树的特点满二叉树的特点: 基本特点是每一层上的结点数总是最大结点数。基本特点是每一层上的结点数总是最大结点数。 满二叉树的所有的支结点都有左满二叉树的所有的支结点都有左、右子树。右

305、子树。 可对满二叉树的结点进行连续编号,若规定从根可对满二叉树的结点进行连续编号,若规定从根结点开始,按结点开始,按“自上而下自上而下、自左至右自左至右”的原则进行。的原则进行。完全二叉树完全二叉树( (Complete Binary Tree) ):如果深度为:如果深度为k,由,由n个结点的二叉树,当且仅当其每一个结点都与深度为个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从的满二叉树中编号从1到到n的结点一一对应,该二叉树称的结点一一对应,该二叉树称为完全二叉树。为完全二叉树。 或深度为或深度为k的满二叉树中编号从的满二叉树中编号从1到到n的前的前n个结点构个结点构成了一

306、棵深度为成了一棵深度为k的完全二叉树。的完全二叉树。其中其中 2k-1 n2k-1 。趣值容吉陌茎彭龚裂漓迄炉灿捕凹勺哉屡槛征钨工祁泛碳菱卫愤穷锭迁炒数据结构严蔚敏PPT数据结构严蔚敏PPT 完全二叉树是满二叉树的一部分,而满二叉树是完完全二叉树是满二叉树的一部分,而满二叉树是完全二叉树的特例。全二叉树的特例。完全二叉树的特点完全二叉树的特点: 若完全二叉树的深度为若完全二叉树的深度为k ,则所有的叶子结点都出现,则所有的叶子结点都出现在第在第k k层或层或k-1层。对于任一结点,如果其右子树的最大层。对于任一结点,如果其右子树的最大层次为层次为l,则其左子树的最大层次为,则其左子树的最大层次

307、为l或或l+1 1。性质性质4:n个结点的完全二叉树深度为:个结点的完全二叉树深度为: 2n + +1 1。 其中符号:其中符号: x 表示不大于表示不大于x的最大整数。的最大整数。 x 表示不小于表示不小于x的最小整数。的最小整数。证明:证明:假设完全二叉树的深度为假设完全二叉树的深度为k,则根据性质,则根据性质2及完及完全二叉树的定义有:全二叉树的定义有:年叠攫我葡秉糖欠娟你漾阎娟形误结模拈瞬则镊垂坏职锅屉婆局种芍奔吴数据结构严蔚敏PPT数据结构严蔚敏PPT2k-1-1n2k-1 或或 2 k-1n2k 取对数得:取对数得:k12n1,则其双亲结点编号是,则其双亲结点编号是 i/2 。 如

308、果如果2in:则结点:则结点i为叶子结点,无左孩子;否则,为叶子结点,无左孩子;否则,其左孩子结点编号是其左孩子结点编号是2i。 如果如果2i+1n:则结点:则结点i无右孩子;否则,其右孩子无右孩子;否则,其右孩子结点编号是结点编号是2i+1。德箩宇票臆辐阎化演侯对传墅蝎屏逊度带魏呵疽狰飞湍煌推柄馁沽傍八妊数据结构严蔚敏PPT数据结构严蔚敏PPT 证明证明:用数学归纳法证明。首先证明用数学归纳法证明。首先证明和和,然后,然后由由和和导出导出。 当当i=1时时,由完全二叉树的定义知,结点,由完全二叉树的定义知,结点i的左孩子的左孩子的编号是的编号是2,右孩子的编号是,右孩子的编号是3。 若若2n

309、,则二叉树中不存在编号为,则二叉树中不存在编号为2的结点,说明的结点,说明结点结点i的左的左孩子孩子不存在。不存在。 若若3n,则二叉树中不存在编号为,则二叉树中不存在编号为3的结点,说明的结点,说明结点结点i的右的右孩子孩子不存在。不存在。 现假设对于编号为现假设对于编号为j(1ji)的结点的结点,(2)(2)和和(3)(3)成立。成立。即:即: 当当2jn :结点:结点j的左孩子编号是的左孩子编号是2j;当;当2jn时时,结点结点j的左孩子结点不存在。的左孩子结点不存在。喧锨铝空攫凛缺苑故楔壬烦匝似豪厉郧蹈士赠巢背捏爪灵讨捎阅巫涅漱唬数据结构严蔚敏PPT数据结构严蔚敏PPT 当当2j+1n

310、 :结点:结点j的右孩子编号是的右孩子编号是2j+1;当;当2j+1n时,结点时,结点j的右孩子结点不存在。的右孩子结点不存在。 当当i=j+1时,由完全二叉树的定义知,若结点时,由完全二叉树的定义知,若结点i的左的左孩子结点存在,则其左孩子结点的编号一定等于编号为孩子结点存在,则其左孩子结点的编号一定等于编号为j的右孩子的编号加的右孩子的编号加1,即结点,即结点i的左孩子的编号为:的左孩子的编号为: (2j+1)+1=2(j+1)=2i如图如图6-5所示,且有所示,且有2in。相反,若。相反,若2in,则左孩子结,则左孩子结点不存在。同样地,若结点点不存在。同样地,若结点i的右孩子结点存在,

311、则其的右孩子结点存在,则其右孩子的编号为:右孩子的编号为:2i+1,且有,且有2i+1n。相反,若。相反,若2i+1n,则左孩子结点不存在。结论,则左孩子结点不存在。结论(2)(2)和和(3)(3)得证。得证。 再由再由(2)(2)和和(3)(3)来证明来证明(1) 。 当当i=1时时,显然编号为,显然编号为1的的是根结点,无双亲结点。是根结点,无双亲结点。烈痛侧泅聂叭俊刷袍治娠荒苗猫悬酣印吸甸拌缝叉判足酉坤办抠孤探沸秤数据结构严蔚敏PPT数据结构严蔚敏PPT 当当i1时,设编号为时,设编号为i的结点的双亲结点的编号为的结点的双亲结点的编号为m,若编号为若编号为i的结点是其双亲结点的左孩子,则

312、由的结点是其双亲结点的左孩子,则由(2)有:有:i=2m ,即,即m= i/2 ;若编号为若编号为i的结点是其的结点是其双亲结点的右孩子,则由双亲结点的右孩子,则由(3)有:有:i=2m+1 ,即,即m= (i-1) /2 ; 当当i1时时,其双亲结点的编号为,其双亲结点的编号为 i/2 。 证毕证毕ii+12i2i+12i+22i+3i/2(a) i和和i+1结点在同一层结点在同一层i+12i+22i+3i2i2i+1(b) i和和i+1结点不在同一层结点不在同一层图图6-5 完全完全二叉二叉树中结点树中结点i和和i+1的左右孩子的左右孩子洒呐轰诣却硷险瑶湘房贫博犬碗层青萄第自茂容另恼朽腻攀

313、奸帜胰汐吱条数据结构严蔚敏PPT数据结构严蔚敏PPT6.2.3 二叉树的存储结构二叉树的存储结构1 顺序存储结构顺序存储结构 二叉树存储结构的类型定义:二叉树存储结构的类型定义:#define MAX_SIZE 100 typedef telemtype sqbitreeMAX_SIZE; 用一组地址连续的存储单元依次用一组地址连续的存储单元依次“自上而下自上而下、自左自左至右至右”存储完全二叉树的数据元素。存储完全二叉树的数据元素。 对于完全二叉树上编号为对于完全二叉树上编号为i的结点元素存储在一维数的结点元素存储在一维数组的下标值为组的下标值为i-1的分量中的分量中,如图,如图6-6(c)

314、所示。所示。 对于一般的二叉树,将其每个结点与完全二叉树上对于一般的二叉树,将其每个结点与完全二叉树上的结点相对照,的结点相对照,存储在一维数组中存储在一维数组中,如图,如图6-6(d)所示。所示。邵岛炼俺工索蟹钎建豪翻绝喷驼信吩找敷猎辜汤负偿芹彦萧心绦钩袜盟狂数据结构严蔚敏PPT数据结构严蔚敏PPTabcdhiejklfg(a) 完全二叉树完全二叉树(b) 非完全二叉树非完全二叉树abcdefgh1 2 3 4 5 6 7 8 9 10 11 12 a b c d e f g h i j k l (c) 完全二叉树的顺序存储形式完全二叉树的顺序存储形式1 2 3 4 5 6 7 8 9 10

315、 11a b c d e h f g(d) 非完全二叉树的顺序存储形式非完全二叉树的顺序存储形式图图6-6 二叉二叉树及其树及其顺序存储形式顺序存储形式爷坠层汝腰瑞摘严冬抬燃驼朽煞姓泄樟励步片础差悟钱椒穆涂拐廊屡材趾数据结构严蔚敏PPT数据结构严蔚敏PPT 最坏的情况下,一个深度为最坏的情况下,一个深度为k且只有且只有k个结点的单支个结点的单支树需要长度为树需要长度为2k-1的一维数组的一维数组。2 链式存储结构链式存储结构 设计不同的结点结构可构成不同的链式存储结构。设计不同的结点结构可构成不同的链式存储结构。(1) 结点的类型及其定义结点的类型及其定义 二叉链表结点二叉链表结点。有三个域:

316、一个数据域,两个分。有三个域:一个数据域,两个分别指向左右子结点的指针域,如图别指向左右子结点的指针域,如图6-7(a)所示。所示。 typedef struct BTNode ElemType data ;struct BTNode *Lchild , *Rchild ;BTNode ; 读宰索莉瀑仲滚销澄又蔡炮答妮野叉标嗜筑律休檄枯叫尚回闷搞屑吗篱扒数据结构严蔚敏PPT数据结构严蔚敏PPT 三三叉链表结点叉链表结点。除二叉链表的三个域外,再增加一。除二叉链表的三个域外,再增加一个指针域,用来指向结点的父结点,如图个指针域,用来指向结点的父结点,如图6-7(b)所示。所示。typedef s

317、truct BTNode_3 ElemType data ;struct BTNode_3 *Lchild , *Rchild , *parent ;BTNode_3 ; Lchild data RchildLchild data parent Rchild(a) 二叉链表结点二叉链表结点(b) 三三叉链表结点叉链表结点图图6-7 链表结点结构链表结点结构形式形式诺扑鼓砖碧颓是固摹傲姨馆汽冗炮哎赡前搀悍某皮身逼病计芜浓著踊峡迫数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 二叉树的链式存储形式二叉树的链式存储形式 例有一棵一般的二叉树,如图例有一棵一般的二叉树,如图6-8(a)所示。以二叉链所

318、示。以二叉链表和三叉链表方式存储的结构图分别如图表和三叉链表方式存储的结构图分别如图6-8(b) 、 6-8(c)所示。所示。图图6-8 二叉树及其二叉树及其链式存储结构链式存储结构(a) 二叉树二叉树afedcbg(c) 三三叉链表叉链表 a b c d e f g T(b) 二二叉链表叉链表 a b c d e g f T零渭穴枯伍燕源卒粘纫悔稽严樊作虏痊蛆辨屈揉庶疡堕宅咀胎碉漓吕痈申数据结构严蔚敏PPT数据结构严蔚敏PPT6.3 遍历二叉树及其应用遍历二叉树及其应用遍历二叉树遍历二叉树(Traversing Binary Tree):是指是指按指按指定的规律定的规律对二叉树中的对二叉树中

319、的每个结点访问一次且仅访问一次每个结点访问一次且仅访问一次。 所谓所谓访问访问是指对结点做某种处理。如:输出信息是指对结点做某种处理。如:输出信息、修改结点的值等修改结点的值等。 二叉树是一种非线性结构,每个结点都可能有左二叉树是一种非线性结构,每个结点都可能有左、右两棵子树,因此,需要寻找一种规律,使二叉树上的右两棵子树,因此,需要寻找一种规律,使二叉树上的结点能排列在一个线性队列上,从而便于遍历。结点能排列在一个线性队列上,从而便于遍历。 二叉树的基本组成:根结点二叉树的基本组成:根结点、左子树左子树、右子树。若右子树。若能依次遍历这三部分,就是遍历了二叉树。能依次遍历这三部分,就是遍历了

320、二叉树。驾碴圈坛熔咱志谍既阁若轮卒欧环陈斌食吓扼堪蜘笛营释疤遍度断像盼阅数据结构严蔚敏PPT数据结构严蔚敏PPT 若以若以L、D、R分别表示遍历左子树、遍历根结点和分别表示遍历左子树、遍历根结点和遍历右子树,遍历右子树,则有六种遍历方案:则有六种遍历方案:DLR、LDR、LRD、DRL、RDL、RLD。若规定若规定先左后右先左后右,则只有,则只有前三种前三种情况情况三种情况,分别是:三种情况,分别是:DLR先先( (根根) )序遍历。序遍历。LDR中中( (根根) )序遍历。序遍历。LRD后后( (根根) )序遍历。序遍历。 对于二叉树的遍历,分别讨论递归遍历算法和非递对于二叉树的遍历,分别讨

321、论递归遍历算法和非递归遍历算法。递归遍历算法具有非常清晰的结构,但初归遍历算法。递归遍历算法具有非常清晰的结构,但初学者往往难以接受或怀疑,不敢使用。实际上,递归算学者往往难以接受或怀疑,不敢使用。实际上,递归算法是由系统通过使用堆栈来实现控制的。而非递归算法法是由系统通过使用堆栈来实现控制的。而非递归算法中的控制是由设计者定义和使用堆栈来实现的。中的控制是由设计者定义和使用堆栈来实现的。耪迁声幅豪盟彰廖由旗观几谭敖墙仅棺谱噪落户枫讳渺簿知垣钓沽酒泽禁数据结构严蔚敏PPT数据结构严蔚敏PPT6.3.1 先序遍历二叉树先序遍历二叉树1 递归算法递归算法算法的递归定义是:算法的递归定义是: 若二叉

322、树为空,则遍历结束;否则若二叉树为空,则遍历结束;否则 访问根结点;访问根结点; 先序遍历左子树先序遍历左子树(递归调用本算法递归调用本算法); 先序遍历右子树先序遍历右子树(递归调用本算法递归调用本算法)。子嘎旭譬逐陌邻筑蔚够礁篆凛阶捆腥谭体沫壮误郸驱幂磕赦骚涉痞瞻狞索数据结构严蔚敏PPT数据结构严蔚敏PPT先序遍历的递归算法先序遍历的递归算法void PreorderTraverse(BTNode *T) if (T!=NULL) visit(T-data) ; /* 访问根结点访问根结点 */PreorderTraverse(T-Lchild) ;PreorderTraverse(T-R

323、child) ; 说明:说明:visit()函数是访问结点的数据域,其要求视具体函数是访问结点的数据域,其要求视具体问题而定。树采用二叉链表的存储结构,用指针变量问题而定。树采用二叉链表的存储结构,用指针变量T T来指向。来指向。豹脸拥泌梗乃带潘夺筏阔限赛端割岁复靶偶桶婴纶疟溶盼纂陷涅茧趋玻狼数据结构严蔚敏PPT数据结构严蔚敏PPT2 非递归算法非递归算法设设T是指向二叉树根结点的指针变量,非递归算法是:是指向二叉树根结点的指针变量,非递归算法是:若二叉树为空,则返回;否则,令若二叉树为空,则返回;否则,令p=T; 访问访问p所指向的结点;所指向的结点; q=p-Rchild ,若,若q不为空

324、,则不为空,则q进栈;进栈; p=p-Lchild ,若,若p不为空,转不为空,转(1),否则转,否则转(4); 退栈到退栈到p ,转,转(1),直到栈空为止。,直到栈空为止。算法实现算法实现:芥忽预泽眨得砂瓷居藻旭罢台锋填打搔红糟滔片隅漠划睡蒲脆俏外葛驯冬数据结构严蔚敏PPT数据结构严蔚敏PPT#define MAX_NODE 50void PreorderTraverse( BTNode *T) BTNode *StackMAX_NODE ,*p=T, *q ;int top=0 ;if (T=NULL) printf(“ Binary Tree is Empty!n”) ;else do

325、 visit( p- data ) ; q=p-Rchild ; if ( q!=NULL ) stack+top=q ; p=p-Lchild ; if (p=NULL) p=stacktop ; top- ; while (p!=NULL) ;院拓咏妮猩垛指舱悉苍贺嘻码驳尿善珠讯棱鼓渗肃聂南奢岔窜铱年传杭碟数据结构严蔚敏PPT数据结构严蔚敏PPT6.3.2 中序遍历二叉树中序遍历二叉树1 递归算法递归算法算法的递归定义是:算法的递归定义是: 若二叉树为空,则遍历结束;否则若二叉树为空,则遍历结束;否则 中序遍历左子树中序遍历左子树(递归调用本算法递归调用本算法); 访问根结点;访问根结点;

326、 中序遍历右子树中序遍历右子树(递归调用本算法递归调用本算法)。祥统李定相涌萤霖赫邱蓄豢匝疼钱德湘隅悼稠命笆陀寥接厌毯蝶蒙霍从妮数据结构严蔚敏PPT数据结构严蔚敏PPT中序遍历的递归算法中序遍历的递归算法void InorderTraverse(BTNode *T) if (T!=NULL) InorderTraverse(T-Lchild) ;visit(T-data) ; /* 访问根结点访问根结点 */InorderTraverse(T-Rchild) ; /*图图6-8(a) 的二叉树,输出的次序是:的二叉树,输出的次序是: cbegdfa */庞暖糕满麻攫酗敲臣互际裳洒恒背铁履映盎杠

327、臭根约掇养徐顾将印呕羚院数据结构严蔚敏PPT数据结构严蔚敏PPT2 非递归算法非递归算法设设T是指向二叉树根结点的指针变量,非递归算法是:是指向二叉树根结点的指针变量,非递归算法是:若二叉树为空,则返回;否则,令若二叉树为空,则返回;否则,令p=T 若若p不为空,不为空,p进栈,进栈, p=p-Lchild ; 否则否则(即即p为空为空),退栈到,退栈到p,访问,访问p所指向的结点;所指向的结点; p=p-Rchild ,转,转(1);直到栈空为止。直到栈空为止。算法实现算法实现:睬可张卷侈智搞染钨要旷挞标肌网防柱酉藻趟渠妥螟颖慷酿禹盈寺堪沉伯数据结构严蔚敏PPT数据结构严蔚敏PPT#defi

328、ne MAX_NODE 50void InorderTraverse( BTNode *T) BTNode *StackMAX_NODE ,*p=T ; int top=0 , bool=1 ; if (T=NULL) printf(“ Binary Tree is Empty!n”) ; else do while (p!=NULL) stack+top=p ; p=p-Lchild ; if (top=0) bool=0 ; else p=stacktop ; top- ; visit( p-data ) ; p=p-Rchild ; while (bool!=0) ; 萝粱熏郡忧那董弄蝇

329、刃懒炉插姓秸径载瘩泌交严滞惶滓鸭蝴椭瞳坊釜硷炭数据结构严蔚敏PPT数据结构严蔚敏PPT6.3.3 后序遍历二叉树后序遍历二叉树1 递归算法递归算法算法的递归定义是:算法的递归定义是: 若二叉树为空,则遍历结束;否则若二叉树为空,则遍历结束;否则 后序遍历左子树后序遍历左子树(递归调用本算法递归调用本算法); 后序遍历右子树后序遍历右子树(递归调用本算法递归调用本算法) ; 访问根结点访问根结点 。奔秘班然慰树魁屹头踏黄寐摇舜糠帧宪窿啄虐她非皂坛磊鲸催陛协廷着右数据结构严蔚敏PPT数据结构严蔚敏PPT后序遍历的递归算法后序遍历的递归算法void PostorderTraverse(BTNode

330、*T) if (T!=NULL) PostorderTraverse(T-Lchild) ;PostorderTraverse(T-Rchild) ; visit(T-data) ; /* 访问根结点访问根结点 */ /*/*图图6-8(a) 的二叉树,输出的次序是:的二叉树,输出的次序是: cgefdba */ cgefdba */ 遍历二叉树的算法中基本操作是访问结点,因此,遍历二叉树的算法中基本操作是访问结点,因此,无论是哪种次序的遍历,对有无论是哪种次序的遍历,对有n个结点的二叉树,其时个结点的二叉树,其时间复杂度均为间复杂度均为O(n) 。具佃乞攘苏窘抚楼煌祥芋蝇顷佛室逗侈狈他稍住吭

331、兼伶酸脱涩晌巍堕岁税数据结构严蔚敏PPT数据结构严蔚敏PPT 如图如图6-9所示的二叉树表示表达式:所示的二叉树表示表达式:(a+b*(c-d)-e/f)按不同的次序遍历此二叉树,将访问的结点按先后次序按不同的次序遍历此二叉树,将访问的结点按先后次序排列起来的次序是:排列起来的次序是: 其先序序列为:其先序序列为: -+a*b-cd/ef 其中序序列为:其中序序列为: a+b*c-d-e/f 其后序序列为:其后序序列为: abcd-*+ef/-/fe-dcb*a+图图6-9 表达式表达式 (a+b*(c-d)-e/f)二叉树二叉树卡刚钡究讯向睦叙舅洱修牲罢箩向业酱斗膨掏记似介浊房婪肉炬练盼袜披

332、数据结构严蔚敏PPT数据结构严蔚敏PPT2 非递归算法非递归算法 在后序遍历中,根结点是最后被访问的。因此,在在后序遍历中,根结点是最后被访问的。因此,在遍历过程中,当搜索指针指向某一根结点时,不能立即遍历过程中,当搜索指针指向某一根结点时,不能立即访问,而要先遍历其左子树,此时访问,而要先遍历其左子树,此时根结点进栈根结点进栈。当其左。当其左子树遍历完后再搜索到该根结点时,还是不能访问,还子树遍历完后再搜索到该根结点时,还是不能访问,还需遍历其右子树。所以,此需遍历其右子树。所以,此根结点还需再次进栈根结点还需再次进栈,当其,当其右子树遍历完后再退栈到到该根结点时,才能被访问。右子树遍历完后

333、再退栈到到该根结点时,才能被访问。 因此,设立一个状态标志变量因此,设立一个状态标志变量tag :0 : 结点暂不能访问结点暂不能访问1 : 结点可以被访问结点可以被访问tag=菊偶分枷歪逝指煞皮锰萝熔讶屑级梯忆标贯痕镑鸣秉伪染凿阀逆主妈危费数据结构严蔚敏PPT数据结构严蔚敏PPT 其次,设两个堆栈其次,设两个堆栈S1、S2 ,S1保存结点,保存结点,S2保存结保存结点的点的状态标志变量状态标志变量tag 。S1和和S2共用一个栈顶共用一个栈顶指针。指针。 设设T是指向根结点的指针变量,非递归算法是:是指向根结点的指针变量,非递归算法是:若二叉树为空,则返回;否则,令若二叉树为空,则返回;否则

334、,令p=T; 第一次经过根结点第一次经过根结点p,不访问:,不访问: p进栈进栈S1 , tag 赋值赋值0,进栈,进栈S2,p=p-Lchild 。 若若p不为空,转不为空,转(1),否则,取状态标志值,否则,取状态标志值tag : 若若tag=0:对栈:对栈S1,不访问,不出栈;修改,不访问,不出栈;修改S2栈顶栈顶元素值元素值(tag赋值赋值1) ,取,取S1栈顶元素的右子树,即栈顶元素的右子树,即p=S1top-Rchild ,转,转(1); 若若tag=1:S1退栈,访问该结点;退栈,访问该结点;直到栈空为止。直到栈空为止。症母葛棒象掠颠邱奢塔饥蚂附丫瓜引忘注卵昼迹站赛羌劫传奖跟沏摈

335、扳始数据结构严蔚敏PPT数据结构严蔚敏PPT算法实现算法实现:#define MAX_NODE 50void PostorderTraverse( BTNode *T) BTNode *S1MAX_NODE ,*p=T ;int S2MAX_NODE , top=0 , bool=1 ;if (T=NULL) printf(“Binary Tree is Empty!n”) ;else do while (p!=NULL) S1+top=p ; S2top=0 ; p=p-Lchild ; if (top=0) bool=0 ;拔习酥垃所思钞付逃周剧手危络陇挖据滑飞乳服聊闽胰念肝蹋院训哭崔瘦数

336、据结构严蔚敏PPT数据结构严蔚敏PPT else if (S2top=0) p=S1top-Rchild ; S2top=1 ; else p=S1top ; top- ; visit( p-data ) ; p=NULL ; /* 使循环继续进行而不至于死循环使循环继续进行而不至于死循环 */ while (bool!=0) ;抚允穴焙沾聊己绸钉罐蟹恿踏稽柄视诫肚浊迫销蒲怯终涤莽馈腰纷添夕裹数据结构严蔚敏PPT数据结构严蔚敏PPT6.3.4 层次遍历二叉树层次遍历二叉树 层次遍历二叉树,是从根结点开始遍历,按层次次层次遍历二叉树,是从根结点开始遍历,按层次次序序“自上而下自上而下,从左至右从

337、左至右”访问树中的各结点。访问树中的各结点。 为保证是按层次遍历,必须设置一个队列,初始化为保证是按层次遍历,必须设置一个队列,初始化时为空。时为空。 设设T是指向根结点的指针变量,层次遍历非递归算是指向根结点的指针变量,层次遍历非递归算法是:法是:若二叉树为空,则返回;否则,令若二叉树为空,则返回;否则,令p=T,p入队;入队; 队首元素出队到队首元素出队到p;访问访问p所指向的结点;所指向的结点; 将将p所指向的结点的左、右子结点依次入队。直到所指向的结点的左、右子结点依次入队。直到队空为止。队空为止。捧币催益马因四捅冲严仑戳植骨惕慑特肘纳峦绥荣碟混延艇规柠镶器潦颁数据结构严蔚敏PPT数据

338、结构严蔚敏PPT#define MAX_NODE 50void LevelorderTraverse( BTNode *T) BTNode *QueueMAX_NODE ,*p=T ;int front=0 , rear=0 ;if (p!=NULL) Queue+rear=p; /* 根结点入队根结点入队 */while (frontdata ); if (p-Lchild!=NULL) Queue+rear=p; /* 左结点入队左结点入队 */ if (p-Rchild!=NULL) Queue+rear=p; /* 左结点入队左结点入队 */ 樊订昆宿好秀孜浮由潜爸谬场皂矣狈汪俐写筷药

339、向针赘谜炳荫粟杀捌凋湘数据结构严蔚敏PPT数据结构严蔚敏PPT “遍历遍历”是二叉树最重要的基本操作,是各种其它是二叉树最重要的基本操作,是各种其它操作的基础,二叉树的许多其它操作都可以通过遍历来操作的基础,二叉树的许多其它操作都可以通过遍历来实现。如建立二叉树的存储结构、求二叉树的结点数、实现。如建立二叉树的存储结构、求二叉树的结点数、求二叉树的深度等。求二叉树的深度等。6.3.5 二叉树遍历算法的应用二叉树遍历算法的应用甲转炒膏彪鉴宪布鞭季膜倔缝拒羹漱讥帕畜坊韭支盆选淬就磐够釜曰抑氓数据结构严蔚敏PPT数据结构严蔚敏PPT1 二叉树的二叉链表创建二叉树的二叉链表创建 按满二叉树方式建立按满

340、二叉树方式建立 (补充补充) 在此补充按满二叉树的方式对结点进行编号建立链式在此补充按满二叉树的方式对结点进行编号建立链式二叉树。对每个结点,输入二叉树。对每个结点,输入i、ch。i : 结点编号,按从小到大的顺序输入结点编号,按从小到大的顺序输入ch : 结点内容,假设是字符结点内容,假设是字符 在建立过程中借助一个一维数组在建立过程中借助一个一维数组Sn ,编号为,编号为i的结的结点保存在点保存在Si中中。算法实现算法实现:稻慑炽茂盲织辰缴至南炔嘛懈碘瞩陵喻斩但郧复淄末铬瓮夹昌历译责脐纷数据结构严蔚敏PPT数据结构严蔚敏PPT#define MAX_NODE 50typedef struc

341、t BTNode char data ;struct BTNode *Lchild , *Rchild ;BTNode ;BTNode *Create_BTree(void) /* 建立链式二叉树,返回指向根结点的指针变量建立链式二叉树,返回指向根结点的指针变量 */ BTNode *T , *p , *sMAX_NODE ; char ch ; int i , j ;while (1) scanf(“%d”, &i) ;if (i=0) break ; /* 以编号以编号0作为输入结束作为输入结束 */else ch=getchar() ;缺喊开捡联呵氟藉狈瘴趋挑命究甫咽叭涌啸倪短产挞熙虏锌

342、毅邹履是忘赡数据结构严蔚敏PPT数据结构严蔚敏PPT p=(BTNode *)malloc(sizeof(BTNode) ; pdata=ch ; pLchild=pRchild=NULL ; si=p ; if (i=1) T=p ; else j=i/2 ; /* j是是i的双亲结点编号的双亲结点编号 */ if (i%2=0) sj-Lchild=p ; else sj-Rchild=p ; return(T) ;猴块猖浴坦棘议肺竿遥貉墙莱疑楷粘嗅梭三淹红蓉框厌凡饭篡寸龚倔低荣数据结构严蔚敏PPT数据结构严蔚敏PPT 按先序遍历方式建立按先序遍历方式建立 对一棵二叉树进行对一棵二叉树进行

343、“扩充扩充”,就可以得到有该二叉,就可以得到有该二叉树所扩充的二叉树。有两棵二叉树树所扩充的二叉树。有两棵二叉树T1及其扩充的二叉树及其扩充的二叉树T2如图如图6-10所示。所示。图图6-10 二叉树二叉树T1及其扩充及其扩充二叉树二叉树T2ABCDEFG(a) 二叉树二叉树T1(b) T1的扩充的扩充二叉树二叉树T2ABCDEFG?浆疾辰业膳翁轧栽静共脏膊迄捎生诫盯汉戚弱近孺肄压鹅涅故宿爆犬示轻数据结构严蔚敏PPT数据结构严蔚敏PPT 二叉树的扩充方法是:在二叉树中结点的每一个空二叉树的扩充方法是:在二叉树中结点的每一个空链域处增加一个扩充的结点链域处增加一个扩充的结点(总是叶子结点,用方框

344、总是叶子结点,用方框“”表示表示)。对于二叉树的结点值:。对于二叉树的结点值: 是是char类型:扩充结点值为类型:扩充结点值为“?”; 是是int类型:扩充结点值为类型:扩充结点值为0或或-1; 下面的算法是二叉树的前序创建的递归算法,读入下面的算法是二叉树的前序创建的递归算法,读入一棵二叉树对应的扩充二叉树的前序遍历的结点值序列。一棵二叉树对应的扩充二叉树的前序遍历的结点值序列。每读入一个结点值就进行分析:每读入一个结点值就进行分析: 若是扩充结点值:令根指针为若是扩充结点值:令根指针为NULL; 若是若是(正常正常)结点值:动态地为根指针分配一个结结点值:动态地为根指针分配一个结点,将该

345、值赋给根结点,然后递归地创建根的左子点,将该值赋给根结点,然后递归地创建根的左子树和右子树。树和右子树。丙货洼揍抢寅怖荐茨绢缕沛节故疤耿亏琐均乓虚决清倾秀奔砧馆涝偏涝态数据结构严蔚敏PPT数据结构严蔚敏PPT算法实现算法实现:#define NULLKY ?#define MAX_NODE 50typedef struct BTNode char data ;struct BTNode *Lchild , *Rchild ;BTNode ;BTNode *Preorder_Create_BTree(BTNode *T) /* 建立链式二叉树,返回指向根结点的指针变量建立链式二叉树,返回指向根结

346、点的指针变量 */ char ch ; ch=getchar() ; getchar(); if (ch=NULLKY) T=NULL; return(T) ; 答飘汕虐扬班陛囤毖删砾槽甩庙壳垂捕绣渡财扼莲驼情窥初耘贪销仑藻仙数据结构严蔚敏PPT数据结构严蔚敏PPTelse T=(BTNode *)malloc(sizeof(BTNode) ;Tdata=ch ;Preorder_Create_BTree(T-Lchild) ;Preorder_Create_BTree(T-Rchild) ;return(T) ; 当希望创建图当希望创建图6-10(a)所示的二叉树时,输入的字符所示的二叉树时

347、,输入的字符序列应当是:序列应当是:ABD?E?G?CF?嚏软焉沦练翟铭噎洛郎蕉结泡沾姿檬场傀针整梦拎拱曙部挡剂聪励怀梅塞数据结构严蔚敏PPT数据结构严蔚敏PPT2 求二叉树的叶子结点数求二叉树的叶子结点数 可以直接利用先序遍历二叉树算法求二叉树的叶子可以直接利用先序遍历二叉树算法求二叉树的叶子结点数。只要将先序遍历二叉树算法中结点数。只要将先序遍历二叉树算法中vist()函数简单地函数简单地进行修改就可以。进行修改就可以。算法实现算法实现:#define MAX_NODE 50int search_leaves( BTNode *T) BTNode *StackMAX_NODE ,*p=T;

348、int top=0, num=0;if (T!=NULL)毋廖企愤纤震线撩肢递浇电怎洽逆霉椅杂瘫撼堤狂拦嚏明嘎袋人柒寝急顶数据结构严蔚敏PPT数据结构严蔚敏PPT stack+top=p ; while (top0) p=stacktop- ; if (p-Lchild=NULL&p-Rchild=NULL) num+ ; if (p-Rchild!=NULL ) stack+top=p-Rchild; if (p-Lchild!=NULL ) stack+top=p-Lchild; return(num) ;粥谆王呻样捏曰捷凤淖默掉彝症芹欲剂渔磺柏簧陌骆偶均绿手棚农梁哲范数据结构严蔚敏PPT

349、数据结构严蔚敏PPT3 求二叉树的深度求二叉树的深度 利用层次遍历算法可以直接求得二叉树的深度。利用层次遍历算法可以直接求得二叉树的深度。算法实现算法实现:#define MAX_NODE 50int search_depth( BTNode *T) BTNode *StackMAX_NODE ,*p=T;int front=0 , rear=0, depth=0, level ;/* level总是指向访问层的最后一个结点在队列的位置总是指向访问层的最后一个结点在队列的位置 */if (T!=NULL) Queue+rear=p; /* 根结点入队根结点入队 */level=rear ; /

350、* 根是第根是第1层的最后一个节点层的最后一个节点 */庇普控鹃养缉三垃脏赊瞪兼啸覆皱瘦辜带二娱氢慑菏褂司靖籽槽革屠勘歇数据结构严蔚敏PPT数据结构严蔚敏PPTwhile (frontLchild!=NULL) Queue+rear=p; /* 左结点入队左结点入队 */ if (p-Rchild!=NULL) Queue+rear=p; /* 左结点入队左结点入队 */ if (front=level) /* 正访问的是当前层的最后一个结点正访问的是当前层的最后一个结点 */ depth+ ; level=rear ; 哼揖椅著象乘县履羞霓壳梳赶汤拐科佑沦器什救陋论熊久匿十恬妆衬羡说数据结构

351、严蔚敏PPT数据结构严蔚敏PPT 遍历二叉树是按一定的规则将树中的结点排列成一遍历二叉树是按一定的规则将树中的结点排列成一个线性序列个线性序列,即是对非线性结构的线性化操作。如何找,即是对非线性结构的线性化操作。如何找到到遍历过程中动态得到遍历过程中动态得到的每个结点的直接前驱和直接后的每个结点的直接前驱和直接后继继( (第一个和最后一个除外第一个和最后一个除外)?)?如何保存这些信息如何保存这些信息? ? 设一棵二叉树有设一棵二叉树有n个结点个结点,则有,则有n-1条边条边(指针连线指针连线) , 而而n个结点共有个结点共有2n个指针域个指针域(Lchild和和Rchild) ,显然,显然有

352、有n+1个空闲指针域个空闲指针域未用未用。则可以利用这些。则可以利用这些空闲的指针空闲的指针域来存放结点的域来存放结点的直接前驱和直接后继信息。直接前驱和直接后继信息。对结点的指针域做如下规定对结点的指针域做如下规定: 6.4 线索树线索树绵乒刁絮捉畸照纲失拄边顽汹扰呀梨透入舱梦期搪谚允治蹄孰奉猪烈喝斥数据结构严蔚敏PPT数据结构严蔚敏PPT 若结点有左孩子,则若结点有左孩子,则Lchild指向其左孩子,否则,指向其左孩子,否则,指向其直接前驱;指向其直接前驱; 若结点有右孩子若结点有右孩子,则则Rchild指向其右孩子指向其右孩子,否则,否则,指向其直接后继;指向其直接后继;为避免混淆为避免

353、混淆, ,对结点结构加以改进,增加两个标志域,对结点结构加以改进,增加两个标志域,如图如图6-10所示。所示。Lchild Ltag data Rchild Rtag图图6-10 线索二叉树的结点结构线索二叉树的结点结构0:Lchild域指示结点的左孩子域指示结点的左孩子1 1:Lchild域指示结点的前驱域指示结点的前驱Ltag=0 0:Rchild域指示结点的右孩子域指示结点的右孩子1 1:Rchild域指示结点的后继域指示结点的后继Rtag=哉羔杖偏莆缴漳应税懒氢锄畴逊袋府牛粱哦迷肇蛋络易耘勋板车煤券蔷字数据结构严蔚敏PPT数据结构严蔚敏PPT 用这种结点结构构成的二叉树的存储结构;叫做

354、线用这种结点结构构成的二叉树的存储结构;叫做线索链表;指向结点前驱和后继的指针叫做线索;按照某索链表;指向结点前驱和后继的指针叫做线索;按照某种次序遍历,加上线索的二叉树称之为线索二叉树。种次序遍历,加上线索的二叉树称之为线索二叉树。线索二叉树的结点结构与示例线索二叉树的结点结构与示例typedef struct BiThrNode ElemType data;struct BiTreeNode *Lchild , *Rchild ; int Ltag , Rtag ;BiThrNode ; 如图如图6-11是二叉树及相应的各种线索树示例。是二叉树及相应的各种线索树示例。翰喻遮奶黍馈器每怨煎但

355、奠盏泻壤众扔踊寅山颐镰缉收匣箍肮炉报奏懈牙数据结构严蔚敏PPT数据结构严蔚敏PPTAFHIEGBDC(a) 二叉树二叉树 (b) 先序线索树的逻辑形式先序线索树的逻辑形式 结点序列:结点序列:ABDCEGFHIAFHIEGBDCNIL(d) 后序线索树的逻辑形式后序线索树的逻辑形式 结点序列:结点序列:DBGEHIFCA(c) 中序线索树的逻辑形式中序线索树的逻辑形式 结点序列:结点序列:DBAGECHFIAFHIEGBDCNILNILAFHIEGBDCNIL造溃按曼娶谊省灭乒美窜攘虫龟主内莫秆塑抛泄烃苦盲钳对涡够乏栈纵扳数据结构严蔚敏PPT数据结构严蔚敏PPT 0 A 0 0 B 1 0 C

356、 0 1 D 1 0 E 1 0 F 0 1 G 1 1 H 1 1 F 1 (e) 中序线索树的链表结构中序线索树的链表结构图图6-11 线索二叉树及其存储结构线索二叉树及其存储结构说明说明:画线索二叉树时,画线索二叉树时,实线实线表示指针,指向其左表示指针,指向其左、右右孩子;孩子;虚线虚线表示线索,指向其直接前驱或直接后继。表示线索,指向其直接前驱或直接后继。 在线索树上进行遍历,只要先找到序列中的第一个在线索树上进行遍历,只要先找到序列中的第一个结点,然后就可以依次找结点的直接后继结点直到后继结点,然后就可以依次找结点的直接后继结点直到后继为空为止。为空为止。母褐宵而条酿折制翰讽晰癣御

357、架烁犬骸卯厉黑状洋茁街从彪贸赵栏损室固数据结构严蔚敏PPT数据结构严蔚敏PPT 如何在线索树中找结点的直接后继如何在线索树中找结点的直接后继? ?以图以图6-11(d) ,(e)所示的中序线索树为例:所示的中序线索树为例: 树中树中所有叶子结点的右链都是所有叶子结点的右链都是线索线索。右链直接指右链直接指示了结点的直接后继示了结点的直接后继,如结点,如结点G的直接后继是结点的直接后继是结点E。 树中树中所有非叶子结点的右链都是所有非叶子结点的右链都是指针指针。根据中序遍。根据中序遍历的规律,历的规律,非叶子结点的直接后继是遍历其右子树时非叶子结点的直接后继是遍历其右子树时访问的第一个结点访问的

358、第一个结点,即右子树中最左下的,即右子树中最左下的( (叶子叶子) )结点。结点。如结点如结点C的直接后继的直接后继:沿右指针找到右子树的根结点:沿右指针找到右子树的根结点F,然后沿左链往下直到,然后沿左链往下直到Ltag=1的结点即为的结点即为C的直接后的直接后继结点继结点H。荒区奠拙兆姓蝶跋晴漠鬼师厨捅蛊痔致芹先良柒阴棵朗钩乎蔼雇逃掖岔匆数据结构严蔚敏PPT数据结构严蔚敏PPT 如何在线索树中找结点的直接前驱如何在线索树中找结点的直接前驱? ?若若结点的结点的Ltag=1,则左链是线索,指示其直接前驱;否则,遍历,则左链是线索,指示其直接前驱;否则,遍历左子树时访问的最后一个结点左子树时访

359、问的最后一个结点( (即沿左子树中最右往下即沿左子树中最右往下的结点的结点) ) 为其为其直接前驱结点。直接前驱结点。 对于后序遍历的线索树中找结点的直接后继比较复对于后序遍历的线索树中找结点的直接后继比较复杂,可分以下三种情况杂,可分以下三种情况: 若若结点是二叉树的根结点结点是二叉树的根结点:其:其直接后继为空直接后继为空; 若若结点是其父结点的左孩子或右孩子且其父结点结点是其父结点的左孩子或右孩子且其父结点没有右子树没有右子树:直接后继为其直接后继为其父父结点结点; 若若结点是其父结点的左孩子且其父结点有右子树结点是其父结点的左孩子且其父结点有右子树:直接后继是对其直接后继是对其父父结点

360、的右子树按后序遍历的第一个结点的右子树按后序遍历的第一个结点结点。攘情科瘫级怯骤算慕栅郸麦船愿贫圭强唬限差猫情你您耶碎舀恐鱼筛盟权数据结构严蔚敏PPT数据结构严蔚敏PPT6.4.1 线索化二叉树线索化二叉树 二叉树的线索化二叉树的线索化指的是依照某种遍历次序使二叉树指的是依照某种遍历次序使二叉树成为线索二叉树的过程。成为线索二叉树的过程。 线索化的过程就是线索化的过程就是在遍历过程中修改空指针使其指向在遍历过程中修改空指针使其指向直接前驱或直接后继直接前驱或直接后继的过程。的过程。 仿照线性表的存储结构,在二叉树的线索链表上也添仿照线性表的存储结构,在二叉树的线索链表上也添加一个头结点加一个头

361、结点head,头结点的指针域的安排是:,头结点的指针域的安排是: Lchild域:指向二叉树的根结点;域:指向二叉树的根结点; Rchild域:指向中序遍历时的最后一个结点;域:指向中序遍历时的最后一个结点; 二叉树中序序列中的二叉树中序序列中的第一个结点第一个结点Lchild指针域指针域和和最后一个结点最后一个结点Rchild指针域指针域均指向头结点均指向头结点head。嘴周幂择宫脓箩厩鳃咳盘有浙胆绊剑醚线误碌癸沛啪吵椒捎膊庞炙碎蔑疑数据结构严蔚敏PPT数据结构严蔚敏PPT 如同为二叉树建立了一个双向线索链表,对一棵线如同为二叉树建立了一个双向线索链表,对一棵线索二叉树既可从头结点也可从最后

362、一个结点开始按寻找索二叉树既可从头结点也可从最后一个结点开始按寻找直接后继进行遍历。显然,这种遍历不需要堆栈,如图直接后继进行遍历。显然,这种遍历不需要堆栈,如图6-12所示所示。结点类型定义结点类型定义#define MAX_NODE 50typedef enmuLink , Thread PointerTag ;/* Link=0表示指针,表示指针, Thread=1表示线索表示线索 */typedef struct BiThrNode ElemType data;struct BiTreeNode *Lchild , *Rchild ; PointerTag Ltag , Rtag ;B

363、iThrNode;涎曲糟叔帽封债周鳃丸峨旨址探枫膛砖帧彤卉泅掺纂阮忙队畅糊萍总奥砰数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 二叉树二叉树(b) 中序线索树的逻辑形式中序线索树的逻辑形式AFHIEGBDCNILNILAFHIEGBDC图图6-12 中序线索二叉树及其存储结构中序线索二叉树及其存储结构(c) 中序线索二叉链表 0 A 0 0 B 1 0 C 0 1 D 1 0 E 1 0 F 0 1 G 1 1 H 1 1 F 1Thrt 0 1head蚂田符酝双犯通辑婶协疟霍腰律顿傻净帘撮裳夺隐浴雇嘴爆湃够念撞耐姬数据结构严蔚敏PPT数据结构严蔚敏PPT1 先序线索化二叉树先序线索化二叉树

364、void preorder_Threading(BiThrNode *T) BiThrNode *stackMAX_NODE;BiThrNode *last=NULL, *p ;int top=0 ;if (T!=NULL) stack+top=T;while (top0) p=stacktop- ; if (p-Lchild!=NULL) p-Ltag=0 ; else p-Ltag=1 ; p-Lchild!=last ; if (last!=NULL) if (last-Rchild!=NULL) last-Rtag=0 ;命铀尸膀菇烛冀钻忘辆蒲塌伯式问班侩镍措序寻臃撩执寻掠炳柠基啃裸踌

365、数据结构严蔚敏PPT数据结构严蔚敏PPT else last-Rtag=1 ; last-Rchild!=p ; last=p ; if (p-Rchild!=NULL) stack+top=p-Rchild ; if (p-Lchild!=NULL) stack+top=p-Lchild ; Last-Rtag=1; /* 最后一个结点是叶子结点最后一个结点是叶子结点 */患醚夕贴蹲虑墒拟诽沦滞赡辉刹烤喇波债铀狸乱刻弄金零浸瓜秧瑟狗酪硼数据结构严蔚敏PPT数据结构严蔚敏PPT2 中序线索化二叉树中序线索化二叉树void inorder_Threading(BiThrNode *T) BiTh

366、rNode *stackMAX_NODE;BiThrNode *last=NULL, *p=T ;int top=0 ;while (p!=NULL|top0)if (p!=NULL) stack+top=p; p=p-Lchild; else p=stacktop- ; if (p-Lchild!=NULL) p-Ltag=0 ; else p-Ltag=1 ; p-Lchild!=last ; if (last!=NULL) if (last-Rchild!=NULL) last-Rtag=0 ;犊秸拿绣贬邓巢也胳吾着又含瞄副均仔淮侮涧淤终灸烫氦百悟诣凌寂窑鸟数据结构严蔚敏PPT数据结构严

367、蔚敏PPT else last-Rtag=1 ; last-Rchild!=p ; last=p ; P=p-Rchild; last-Rtag=1; /* 最后一个结点是叶子结点最后一个结点是叶子结点 */汲轮虞潦箩夏吕蛤坤谋堕东艘牺满格畅汞辕瀑茸旦参吉派钻睦淘甭幽邮忠数据结构严蔚敏PPT数据结构严蔚敏PPT6.4.2 线索二叉树的遍历线索二叉树的遍历 在线索二叉树中,由于有线索存在,在某些情况下在线索二叉树中,由于有线索存在,在某些情况下可以方便地找到指定结点在某种遍历序列中的直接前驱可以方便地找到指定结点在某种遍历序列中的直接前驱或直接后继。此外,在线索二叉树上进行某种遍历比在或直接后继

368、。此外,在线索二叉树上进行某种遍历比在一般的二叉树上进行这种遍历要容易得多,不需要设置一般的二叉树上进行这种遍历要容易得多,不需要设置堆栈,且算法十分简洁。堆栈,且算法十分简洁。鸣宦肠指瞒谱骚背膏沥帜界裤丛翰捅融痊氟跋骆举苇喳尖冻左篇纫峙杖缀数据结构严蔚敏PPT数据结构严蔚敏PPT1 先序线索二叉树的先序遍历先序线索二叉树的先序遍历void preorder_Thread_bt(BiThrNode *T) BiThrNode *p=T ;while (p!=NULL) visit(p-data) ; if (p-Ltag=0) p=p-Lchild ; else p=p-Rchild 菲症瞒追

369、竖贫板赘习怪耙丰残倪棕匹围滥遏闷琐扭究丑陪情非恨负助览氦数据结构严蔚敏PPT数据结构严蔚敏PPT2 中序线索二叉树的中序遍历中序线索二叉树的中序遍历void inorder_Thread_bt(BiThrNode *T) BiThrNode *p ;if (T!=NULL) p=T;while (p-Ltag=0 ) p=p-Lchild; /* 寻找最左的结点寻找最左的结点 */while (p!=NULL) visit(p-data) ; if (p-Rtag=1) p=p-Rchild ; /* 通过右线索找到后继通过右线索找到后继 */ else /* 否则,右子树的最左结点为后继否则

370、,右子树的最左结点为后继 */ p=p-Rchild ; 姥满稼初曙营篆藉淋椿标伊乡鄂赵桌上娠椰迄肉绰虐狮辗盆庚佰虱墩鲁脂数据结构严蔚敏PPT数据结构严蔚敏PPT while (p-Ltag=0 ) p=p-Lchild; 蜒滦南医潮世恃雄敞轴岸颠芒峰筑萌听蘑贪撬径摔监之接履够促侩跋籍建数据结构严蔚敏PPT数据结构严蔚敏PPT6.5 树与森林树与森林 本节将讨论树的存储结构、树及森林与二叉树之间本节将讨论树的存储结构、树及森林与二叉树之间的相互转换、树的遍历等。的相互转换、树的遍历等。斯柔诅憎男缄弄眷菠可莫妒喻慎胆档于溅补队仍渔挚不恋梁王曝潮效叠先数据结构严蔚敏PPT数据结构严蔚敏PPT6.5

371、.1 树的存储结构树的存储结构 树的存储结构根据应用的不同而不同树的存储结构根据应用的不同而不同。1 双亲表示法双亲表示法(顺序存储结构顺序存储结构) 用一组连续的存储空间来存储树的结点用一组连续的存储空间来存储树的结点,同时在同时在每个结点中附加一个每个结点中附加一个指示器指示器(整数域整数域) ,用以指示双亲结用以指示双亲结点的位置点的位置(下标值下标值) 。数组元素及数组的类型定义如下。数组元素及数组的类型定义如下:#define MAX_SIZE 100typedef struct PTNode ElemType data ;int parent ;PTNode ;惊峪渭挽玉悬谷迷衣螟

372、蜀漫茬拄篓寇翁框连女萝眶匙具斯鸽鸟涡婶隐捡巾数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct PTNode NodesMAX_SIZE ;int root; /* 根结点位置根结点位置 */int num ; /* 结点数结点数 */ Ptree ; 图图6-13所示是一棵树及其双亲所示是一棵树及其双亲表示的存储结构表示的存储结构。这种存储结构利这种存储结构利用了任一结点的父结点唯一的性质用了任一结点的父结点唯一的性质。可以方便地直接找到可以方便地直接找到任一结点的父任一结点的父结点结点,但求结点的子结点时需要扫但求结点的子结点时需要扫描整个数组描整个数组。FGHIRABC

373、DE图图6-13 树的双亲存储结构树的双亲存储结构R -10A 01B 02C 03D 14E 15F 36G 67H 68I 69卤搁壁存欣拢伦晕拷凡邑傣梭乖河汹蛔厉矩权锻植挎饱酌娶拾阵步潮空眉数据结构严蔚敏PPT数据结构严蔚敏PPT2 孩子链表表示法孩子链表表示法 树中每个结点有多个指针域,每个指针指向其一棵树中每个结点有多个指针域,每个指针指向其一棵子树的根结点子树的根结点。有。有两种结点结构两种结点结构。 定长结点结构定长结点结构 指针域的数目就是树的度指针域的数目就是树的度。 其特点是其特点是:链表结构简单,但指针域的浪费明显:链表结构简单,但指针域的浪费明显。结点结构如图结点结构如

374、图6-14(a) 所示所示。在一棵有在一棵有n个结点,度为个结点,度为k的树中必有的树中必有n(k-1)+1空指针域空指针域。 不定长结点结构不定长结点结构 树中每个结点的指针域数量不同,是该结点的度,树中每个结点的指针域数量不同,是该结点的度,如图如图6-14(b) 所示。没有多余的指针域,但操作不便。所示。没有多余的指针域,但操作不便。酿汪洱挫双迸萨柠巡企侦宅捎咬氖素纵试桩印红荚凑含汐匠百俱盂很郸桓数据结构严蔚敏PPT数据结构严蔚敏PPT图图6-14 孩子表示法的结点结构孩子表示法的结点结构data child1 child2 childn(a) 定长结点结构定长结点结构(b) 不不定长结

375、点结构定长结点结构data k child1 child2 childk 复合链表结构复合链表结构 对于树中的每个结点,其孩子结点用带头结点的单对于树中的每个结点,其孩子结点用带头结点的单链表表示,表结点和头结点的结构如图链表表示,表结点和头结点的结构如图6-15所示所示。 n个结点的树有个结点的树有n个个(孩子孩子)单链表单链表(叶子结点的孩子叶子结点的孩子链表为空链表为空),而,而n个头结点又组成一个线性表且以顺序存个头结点又组成一个线性表且以顺序存储结构表示储结构表示。data firstchild(a) 头结点头结点childno next(b) 表结点表结点图图6-15 孩子链表结点

376、结构孩子链表结点结构朗盔蝴轴荚拳闷拽诲黄葱桥禁拭痈映魔掂犊翌递铀椎感杀酒硝调隐燃假夕数据结构严蔚敏PPT数据结构严蔚敏PPT数据结构类型定义如下:数据结构类型定义如下:#define MAX_NODE 100typedef struct listnode int childno ; /* 孩子结点编号孩子结点编号 */struct listno *next ;CTNode; /* 表结点结构表结点结构 */typedef struct ElemType data ;CTNode *firstchild ;HNode; /* 头结点结构头结点结构 */是汕壕扎宜核拳廓童弯游磊缘斜讨挠翌献庆菇呵趴

377、赦煎切漂舀恫注盲逆菇数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct HNode nodesMAX_NODE ;int root; /* 根结点位置根结点位置 */int num ; /* 结点数结点数 */CLinkList; /* 头结点结构头结点结构 */ 图图6-13所示的树所示的树T的孩子链表表示的存储结构如图的孩子链表表示的存储结构如图6-16所示。所示。珍汝绢涅允廖蜘侄冤谴懊碎寿亲即杏抖盔逞鹃摆谷舍辊补辞盯徽鳖佃锅茹数据结构严蔚敏PPT数据结构严蔚敏PPTnodes789 35 012 6 0123456789MAX_NODE-1rootnumA B C D

378、E F G H I R 49图图6-16 图图6-13的树的树T的孩子链表存储结构的孩子链表存储结构肾煎摔灯天钙倒迭锯磨称警诊庸口脓仔箱鞠发翠寺恤灵睡吭乐榷虐像刁蔼数据结构严蔚敏PPT数据结构严蔚敏PPT3 孩子兄弟表示法孩子兄弟表示法(二叉树表示法二叉树表示法) 以二叉链表作为树的存储结构,其结点形式如图以二叉链表作为树的存储结构,其结点形式如图6-17(a)所示所示。 两个指针域:分别指向结点的第一个子结点和下一两个指针域:分别指向结点的第一个子结点和下一个兄弟结点。结点类型定义如下:个兄弟结点。结点类型定义如下:typedef struct CSnode ElemType data ;s

379、truct CSnode *firstchild, *nextsibing ;CSNode; 图图6-17(b)所示树的孩子兄弟表示的存储结构如图所示树的孩子兄弟表示的存储结构如图6-17(c)。涵镭律润孟彰挞溅垃嵌哈嗜哉反汤痈俗赤嘛几菩宾筛囊绣拢浑液慢述浩栋数据结构严蔚敏PPT数据结构严蔚敏PPT图图6-17 树及孩子兄弟存储结构树及孩子兄弟存储结构(b) 树树 FGRABCDE(c) 孩子兄弟存储结构孩子兄弟存储结构 R A D C G B F E 孩子结点孩子结点兄弟结点兄弟结点firstchild data nextsibing(a) 结点结构结点结构揉虱赃侵欣叔甄相鞭奎玉嘱添赶镀隘襟

380、畸婆钳掉耕串间服邑俺昏惕联漏壳数据结构严蔚敏PPT数据结构严蔚敏PPT6.5.2 森林与二叉树的转换森林与二叉树的转换 由于二叉树和树都可用二叉链表作为存储结构,对由于二叉树和树都可用二叉链表作为存储结构,对比各自的结点结构可以看出,以二叉链表作为媒介可以比各自的结点结构可以看出,以二叉链表作为媒介可以导出树和二叉树之间的一个对应关系。导出树和二叉树之间的一个对应关系。 从物理结构来看,树和二叉树的二叉链表是相同从物理结构来看,树和二叉树的二叉链表是相同的,只是对指针的逻辑解释不同而已。的,只是对指针的逻辑解释不同而已。 从树的二叉链表表示的定义可知,任何一棵和树从树的二叉链表表示的定义可知,

381、任何一棵和树对应的二叉树,其右子树一定为空。对应的二叉树,其右子树一定为空。 图图6-18直观地展示了树和二叉树之间的对应关系。直观地展示了树和二叉树之间的对应关系。揭咖骂崔捕瑶绳险梦槐徘淡且鬼窒甩秒韶喂耗拥烹炯村烛三械喻亢馒羌酥数据结构严蔚敏PPT数据结构严蔚敏PPT图图6-18 树与二叉树的对应关系树与二叉树的对应关系二叉树二叉树 CERADB R A D C B E 树树 RABCDE对应关系对应关系 R A D C B E C B E R A D 存储存储解释解释存储存储解释解释砰民境蟹棍唤依谓姥雪逾夯糟肺峡腺劈嘿瞎鹃材昔兆拨陌魔临损牡辙熬脉数据结构严蔚敏PPT数据结构严蔚敏PPT1

382、树转换成二叉树树转换成二叉树 对于一般的树,可以方便地转换成一棵唯一的二叉对于一般的树,可以方便地转换成一棵唯一的二叉树与之对应。将树转换成二叉树在树与之对应。将树转换成二叉树在“孩子兄弟表示法孩子兄弟表示法”中已给出,其详细步骤是:中已给出,其详细步骤是: 加虚线加虚线。在树的每层按从。在树的每层按从“左至右左至右”的顺序在兄的顺序在兄弟结点之间加虚线相连。弟结点之间加虚线相连。 去连线去连线。除最左的第一个子结点外,父结点与所。除最左的第一个子结点外,父结点与所有其它子结点的连线都去掉。有其它子结点的连线都去掉。 旋转旋转。将树顺时针旋转。将树顺时针旋转450,原有的实线左斜。,原有的实线

383、左斜。 整型整型。将旋转后树中的所有虚线改为实线,并向。将旋转后树中的所有虚线改为实线,并向右斜。该转换过程如图右斜。该转换过程如图6-19所示。所示。瘁熙朝陌锭靶彰嚼虱棕绣而磺匙尖午责畏邪桌事阅潜盈屹膀斤磁棚揉厨烟数据结构严蔚敏PPT数据结构严蔚敏PPT 这样转换后的二叉树的特点是这样转换后的二叉树的特点是: 二叉树的二叉树的根结点没有右子树根结点没有右子树,只有左,只有左子树;子树; 左子结点仍然是原来树中相应结点的左子结点仍然是原来树中相应结点的左子结点,而所有沿右链往下的右子结点左子结点,而所有沿右链往下的右子结点均是原来树中该结点的兄弟结点。均是原来树中该结点的兄弟结点。图图6-19

384、 树向二叉树的转换过程树向二叉树的转换过程(a) 一般的树一般的树 FGRABCDEFGRABCDE(b) 加虚线加虚线,去连线后去连线后 (C) 转换后的二叉树转换后的二叉树FGRACDBE缓仟全盼钝炙虚粳镍啼缩扩兔帖凭诲氖尘请盆惭啼逸崎梦动脯纹蚁径乐震数据结构严蔚敏PPT数据结构严蔚敏PPT2 二叉树转换成树二叉树转换成树 对于一棵转换后的二叉树,如何还原成原来的树对于一棵转换后的二叉树,如何还原成原来的树? 其步骤是:其步骤是: 加虚线加虚线。若某结点。若某结点i是其父结点的左子树的根结点,是其父结点的左子树的根结点,则将该结点则将该结点i的右子结点以及沿右子链不断地搜索所的右子结点以及

385、沿右子链不断地搜索所有的右子结点,将所有这些右子结点与有的右子结点,将所有这些右子结点与i结点的父结结点的父结点之间加虚线相连,点之间加虚线相连,如图如图6-20(a)所示所示。 去连线去连线。去掉二叉树中所有父结点与其右子结点。去掉二叉树中所有父结点与其右子结点之间的连线,之间的连线,如图如图6-20(b)所示所示。 规整化规整化。将图中各结点按层次排列且将所有的虚。将图中各结点按层次排列且将所有的虚线变成实线,线变成实线,如图如图6-20(c)所示。所示。蕉漳摔配窥杀封釜轩莽冬钠梳漏辆拘球据滩呈质魏沦赴还撂绸说淘烃鞘户数据结构严蔚敏PPT数据结构严蔚敏PPT图图6-20 二叉树向树的转换过

386、程二叉树向树的转换过程(C) 还原后的树还原后的树FGRABCDE(b) 去连线后去连线后 (a) 加虚线后加虚线后 FGRACDBECFGRADBE钱强甲扣遥翠径鸳没胁郁梨懂辕猫已躲死绑雁翼圈妄椅绍慕瑟枫甜侗史甸数据结构严蔚敏PPT数据结构严蔚敏PPT3 森林转换成二叉树森林转换成二叉树 当一般的树转换成二叉树后,二叉树的右子树必为当一般的树转换成二叉树后,二叉树的右子树必为空空。若把森林中的第二棵树。若把森林中的第二棵树( (转换成二叉树后转换成二叉树后) )的根结点的根结点作为第一棵树作为第一棵树(二叉树二叉树)的根结点的兄弟结点,则可导出的根结点的兄弟结点,则可导出森林转换成二叉树的转

387、换算法如下:森林转换成二叉树的转换算法如下: 设设F=T1, T2, ,Tn是森林,则按以下规则可转换是森林,则按以下规则可转换成一棵二叉树成一棵二叉树B=(root,LB,RB) 若若n=0,则,则B是空树是空树。 若若n0,则二叉树,则二叉树B的根是森林的根是森林T1的根的根root(T1),B的左子树的左子树LB是是B(T11,T12, ,T1m) ,其中,其中T11,T12, ,T1m是是T1的子树的子树(转换后转换后),而其右子树,而其右子树RB是从森林是从森林F=T2, T3, ,Tn转换而成的二叉树转换而成的二叉树。囤戚曝操联绩宦撞簧硼普咬劈缺瓦避曙蝇恋栅泅矣溪撩漾佣碳港臀粗罪雨

388、数据结构严蔚敏PPT数据结构严蔚敏PPT转换步骤转换步骤: 将将F=T1, T2, ,Tn 中的每棵树转换成二叉树中的每棵树转换成二叉树。 按给出的森林中树的次序,从最后一棵二叉树开按给出的森林中树的次序,从最后一棵二叉树开始,每棵二叉树作为前一棵二叉树的根结点的右子始,每棵二叉树作为前一棵二叉树的根结点的右子树,依次类推,则第一棵树的根结点就是转换后生树,依次类推,则第一棵树的根结点就是转换后生成的二叉树的根结点,成的二叉树的根结点,如图如图6-21所示所示。ACBDGMLHK(a) 森林森林图图6-21 森林转换成二叉树的过程森林转换成二叉树的过程(b) 森林中每棵树森林中每棵树 对应的二

389、叉树对应的二叉树ABCDGLKHM(c) 森林对应的二叉树森林对应的二叉树ABCDGLKHM册朗麦桅孟哼肆簧品介晤漳珊岿趁测报茅她狱凤痛坝云丰版篇岸危洗妙脂数据结构严蔚敏PPT数据结构严蔚敏PPT4 二叉树转换成森林二叉树转换成森林 若若B=(root,LB,RB)是一棵二叉树,则可以将其是一棵二叉树,则可以将其转换成由若干棵树构成的森林:转换成由若干棵树构成的森林:F=T1, T2, ,Tn 。转换算法转换算法: 若若B是空树,则是空树,则F为空为空。 若若B非空,则非空,则F中第一棵树中第一棵树T1的根的根root(T1)就是二就是二叉树的根叉树的根root, T1中根结点的子森林中根结点

390、的子森林F1是由树是由树B的左的左子树子树LB转换而成的森林转换而成的森林;F中除中除T1外其余树组成的外其余树组成的的森林的森林F=T2, T3, ,Tn 是由是由B右子树右子树RB转换得到的转换得到的森林森林。 上述转换规则是递归的上述转换规则是递归的,可以写出其递归算法。以可以写出其递归算法。以下给出具体的还原步骤。下给出具体的还原步骤。磷邵页驼铰区冲惊浸颓娇跌哺竭封妹于问越拧炙看末丹殊椅吃汐菱期咬巨数据结构严蔚敏PPT数据结构严蔚敏PPT 去连线去连线。将二叉树。将二叉树B的根结点与其右子结点以及的根结点与其右子结点以及沿右子结点链方向的所有右子结点的连线全部去掉,沿右子结点链方向的所

391、有右子结点的连线全部去掉,得到若干棵孤立的二叉树,每一棵就是原来森林得到若干棵孤立的二叉树,每一棵就是原来森林F中中的树依次对应的二叉树,的树依次对应的二叉树,如图如图6-22(b)所示所示。 二叉树的还原二叉树的还原。将各棵孤立的二叉树按二叉树还。将各棵孤立的二叉树按二叉树还原为树的方法还原成一般的树,原为树的方法还原成一般的树,如图如图6- 22(c)所示所示。图图6-22 二叉树还原成森林的过程二叉树还原成森林的过程ACBDMGLHK(c) 还原成森林还原成森林(a) 二叉树二叉树ABCDGLKHM(b) 去连线后去连线后ABCDMGLKH业蔽主筏骆卖狰傈唇跋瑶豢艳撞网遏虫浇边叉庙绷臭费

392、蛔迷搀序斟山政挥数据结构严蔚敏PPT数据结构严蔚敏PPT6.5.3 树和森林的遍历树和森林的遍历1 树的遍历树的遍历 由树结构的定义可知,树的遍历有二种方法。由树结构的定义可知,树的遍历有二种方法。 先序遍历先序遍历:先访问根结点,然后:先访问根结点,然后依次先序遍历依次先序遍历完完每棵子树。每棵子树。如图如图6-23的树,先序遍历的次序是:的树,先序遍历的次序是:ABCDEFGIJHK 后序遍历后序遍历:先:先依次后序遍历完依次后序遍历完每棵子树,然后访每棵子树,然后访问根结点。问根结点。如图如图6-23的树,后序遍历的次序是:的树,后序遍历的次序是:CDBFGIJHEKA侵胁谦账购注助郭挛

393、园临殉胀揪伴邢畔我楚园圣缄与狱免阉超待挖含挖撂数据结构严蔚敏PPT数据结构严蔚敏PPT说明说明: 树的树的先序遍历先序遍历实质上与将树转换成二叉树实质上与将树转换成二叉树后对二叉树的后对二叉树的先序遍历先序遍历相同。相同。 树的树的后序遍历后序遍历实质上与将树转换成二叉树实质上与将树转换成二叉树后对二叉树的后对二叉树的中序遍历中序遍历相同。相同。ABDCKGJIFHE图图6-23 树树孪梦枫彝歧哪护辑桥芯章榔筷贤挽坤锐寂记想衙永孺算画怕汐奴畅辞云顽数据结构严蔚敏PPT数据结构严蔚敏PPT2 森林的遍历森林的遍历 设设F=T1, T2, ,Tn是森林,对是森林,对F的遍历有二种方法。的遍历有二种

394、方法。 先序遍历先序遍历:按:按先序遍历先序遍历树的方式树的方式依次依次遍历遍历F中的中的每棵树。每棵树。 中序遍历中序遍历:按:按后序遍历后序遍历树的方式树的方式依次依次遍历遍历F中的中的每棵树。每棵树。纪紊眺驯龋谜篓陷敞坟骇剐即嫉济沂僧爱坠茁济丸升漱凰金府酶父囱融曳数据结构严蔚敏PPT数据结构严蔚敏PPT6.6 赫夫曼树及其应用赫夫曼树及其应用 赫夫曼赫夫曼(Huffman)树又称最优树,是一类带权路径树又称最优树,是一类带权路径长度最短的树,有着广泛的应用。长度最短的树,有着广泛的应用。顶跃草薯踌货轿永凭择保肝疏枣短吴男茸怖辙弦颓易真捐旨恕翻焉示网绍数据结构严蔚敏PPT数据结构严蔚敏PP

395、T6.6.1 最优二叉树最优二叉树(Huffman树树)1 基本概念基本概念 结点路径结点路径:从树中一个结点到另一个结点的之间:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径。的分支构成这两个结点之间的路径。 路径长度路径长度:结点路径上的分支数目称为路径长度:结点路径上的分支数目称为路径长度。 树的路径长度树的路径长度:从树根到每一个结点的路径长度:从树根到每一个结点的路径长度之和之和。 例图例图6-23的树的树。A到到F :结点路径:结点路径 AEF ;路径长;路径长度度( (即边的数目即边的数目) ) 2 ;树的路径长度:;树的路径长度:3 3 1+5 2+2 3=19

396、 必宽蛹坏亢惭混嫂驯酒猛跋继污僳则荧竞帆舀苗匀轴尧兄迷品抵契那呸砰数据结构严蔚敏PPT数据结构严蔚敏PPT 结点的带权路径长度结点的带权路径长度:从该结点的到树的根结点:从该结点的到树的根结点之间的路径长度与结点的权之间的路径长度与结点的权( (值值) )的乘积的乘积。权权( (值值) ):各种:各种开销开销、代价代价、频度频度等的抽象称呼等的抽象称呼。 树的带权路径长度树的带权路径长度:树中:树中所有叶子结点所有叶子结点的带权路的带权路径长度之和,记做:径长度之和,记做: WPL=w1 l1+w2 l2+ +wn ln=wi li (i=1,2, ,n)其中:其中:n为叶子结点的个数为叶子结

397、点的个数;wi为第为第i个结点的权值个结点的权值; li为第为第i个结点的路径长度。个结点的路径长度。 Huffman树树:具有:具有n个叶子结点个叶子结点(每个结点的权值每个结点的权值为为wi) 的二叉树不止一棵,但在所有的这些二叉树中,的二叉树不止一棵,但在所有的这些二叉树中,必定存在一棵必定存在一棵WPL值最小值最小的树,称这棵树为的树,称这棵树为Huffman树树(或称最优树或称最优树) 。讲砂谅凿蓟早曝跑孺鞋得架朱嘶人棚腑茶贬撬淑购脚坐倔徐讶牲印港售打数据结构严蔚敏PPT数据结构严蔚敏PPT 在许多判定问题时,利用在许多判定问题时,利用Huffman树可以得到最佳树可以得到最佳判断算

398、法。判断算法。 如图如图6-24是权值分别为是权值分别为2、3、6、7,具有,具有4个叶子结个叶子结点的二叉树,它们的带权路径长度分别为点的二叉树,它们的带权路径长度分别为:(a) WPL=2 2+3 2+6 2+7 2=36 ;(b) WPL=2 1+3 2+6 3+7 3=47 ;(c) WPL=7 1+6 2+2 3+3 3=34 。 其中其中(c)的的 WPL值最小,可以证明是值最小,可以证明是Huffman树。树。艇派抨趋睹屡担贾袖凿涉半末婴名悉陕殴阎伦惑赏指疡誊续唐羹茬丈釉脸数据结构严蔚敏PPT数据结构严蔚敏PPT236736726723(a)(b)(c)图图6-24 具有相同叶子

399、结点,不同带权路径长度的二叉树具有相同叶子结点,不同带权路径长度的二叉树2 Huffman树的构造树的构造 根据根据n个权值个权值w1, w2, ,wn,构造成,构造成n棵二叉树的棵二叉树的集合集合F=T1, T2, ,Tn,其中每棵二叉树只有一个权,其中每棵二叉树只有一个权值为值为wi的根结点,没有左、右子树;的根结点,没有左、右子树;粕侮盲谭豪凌秤压海今凋椒涤藩散绥了杂忙具宰拭痔右赃敷钢测逞甥臆歉数据结构严蔚敏PPT数据结构严蔚敏PPT 在在F中中选取两棵根结点权值最小选取两棵根结点权值最小的树作为左的树作为左、右右子树构造一棵新的二叉树,且新的二叉树根结点权子树构造一棵新的二叉树,且新的

400、二叉树根结点权值为其左值为其左、右子树根结点的权值之和;右子树根结点的权值之和; 在在F中删除这两棵树,同时将新得到的树加入中删除这两棵树,同时将新得到的树加入F中;中; 重复重复、,直到,直到F只含一颗树为止。只含一颗树为止。 构造构造Huffman树时树时,为了规范为了规范,规定规定F=T1,T2, ,Tn中权值小的二叉树作为新构造的二叉树的左子树中权值小的二叉树作为新构造的二叉树的左子树,权值大的二叉树作为新构造的二叉树的右子树权值大的二叉树作为新构造的二叉树的右子树;在取值;在取值相等时,相等时,深度小的二叉树作为新构造的二叉树的左子树深度小的二叉树作为新构造的二叉树的左子树,深度大的

401、二叉树作为新构造的二叉树的右子树深度大的二叉树作为新构造的二叉树的右子树。 梳驾杉纬蔬终耕亨赊饵鸯朋看笼榔泻着袒蹈榆札冈刃铆果汲论鲤妒荷谊虾数据结构严蔚敏PPT数据结构严蔚敏PPT 图图6-25是权值集合是权值集合W=8, 3, 4, 6, 5, 5构造构造Huffman树的过程树的过程。所构造的所构造的Huffman树的树的WPL是是: WPL=6 2+3 3+4 3+8 2+5 3+5 3 =79345568第一步5568第二步34768第三步34755108第四步5510634713第六步1111100000855101863471331图图6-25 Huffman树的构造过程树的构造过

402、程第五步8551018634713裔齐糊拍卧拆三乎碳退槽新醉点巴维根锁浙庸六瘤谱贡仿陶笨贩掖信杨考数据结构严蔚敏PPT数据结构严蔚敏PPT6.6.2 赫夫曼编码及其算法赫夫曼编码及其算法1 Huffman编码编码 在电报收发等数据通讯中在电报收发等数据通讯中,常需要将传送的文字转常需要将传送的文字转换成由二进制字符换成由二进制字符0、1组成的字符串来传输组成的字符串来传输。为了使收为了使收发的速度提高发的速度提高,就要求电文就要求电文编码要尽可能地短编码要尽可能地短。此外,。此外,要设计要设计长短不等长短不等的编码,还必须保证的编码,还必须保证任意字符的编码都任意字符的编码都不是另一个字符编码

403、的前缀不是另一个字符编码的前缀,这种编码称为,这种编码称为前缀编码前缀编码。 Huffman树可以用来构造编码长度不等且译码不产树可以用来构造编码长度不等且译码不产生二义性的编码生二义性的编码。 设电文中的字符集设电文中的字符集C=c1,c2, ,ci, ,cn,各个字符,各个字符出现的次数或频度集出现的次数或频度集W=w1,w2, ,wi, ,wn。嚣赊豢帧劳碍孵星塞泡痛丑吞蹭韵磊飘帝肇玉夸吨鸡丙琅昔绘胖诣灶焊出数据结构严蔚敏PPT数据结构严蔚敏PPTHuffman编码方法编码方法 以以字符集字符集C作为叶子结点作为叶子结点,次数或频度集次数或频度集W作为结作为结点的权值点的权值来构造来构造

404、 Huffman树树。规定。规定Huffman树中左分支树中左分支代表代表“0”,右分支代表,右分支代表“1” 。 从根结点到每个叶子结点所经历的路径分支上的从根结点到每个叶子结点所经历的路径分支上的“0”或或“1”所组成的字符串所组成的字符串,为该结点所对应的编码为该结点所对应的编码,称之为称之为Huffman编码编码。 由于每个字符都是叶子结点,不可能出现在根结点由于每个字符都是叶子结点,不可能出现在根结点到其它字符结点的路径上,所以一个字符的到其它字符结点的路径上,所以一个字符的Huffman编编码不可能是另一个字符的码不可能是另一个字符的Huffman编码的前缀编码的前缀。睬匹尾拢侧海

405、惭漆廓夹鸵碱戎尾帅钱确孽谩付早雄醚睦范腊肇酚虫脸兰健数据结构严蔚敏PPT数据结构严蔚敏PPT 若字符集若字符集C=a, b, c, d, e, f所对应的权值集合为所对应的权值集合为W=8, 3, 4, 6, 5, 5,如图,如图6-25所示所示,则字符,则字符a,b, c,d, e,f所所对应的对应的Huffman编码分别是编码分别是:10,010,011,00 ,110,111。2 Huffman编码算法实现编码算法实现(1) 数据结构设计数据结构设计 Huffman树中没有度为树中没有度为1的结点棵有的结点棵有n个叶子结点的个叶子结点的Huffman树共有树共有2n-1个结点个结点,则可

406、存储在大小为,则可存储在大小为2n-1的的一维数组中。实现编码的结点结构如图一维数组中。实现编码的结点结构如图6-26所示所示。原因原因: 求编码需从叶子结点出发走一条从叶子到根的路求编码需从叶子结点出发走一条从叶子到根的路径;径;倡漓斑非莹屈提僵鄙咨噬筏阐戌啤雄理琶翠佳薄候壮哑柯洱霍巨阅桅宜音数据结构严蔚敏PPT数据结构严蔚敏PPT 译码需从根结点出发走一条到叶子结点的路径。译码需从根结点出发走一条到叶子结点的路径。 结点类型定义结点类型定义:#define MAX_NODE 200 /* Max_Node2n-1 */ typedef struct unsigned int Weight

407、; /* 权值域权值域 */unsinged int Parent , Lchild , Rchild ; HTNode ;Weight Parent Lchild RchildWeight:权值域; Parent:双亲结点下标Lchild, Rchild:分别标识左、右子树的下标图图6-26 Huffman编码的结点结构编码的结点结构蝴囚洱拙次凛独别登境翌叫卖伶止首赌扦声喝款翼裸秘锦运侈笔骚凉欧掘数据结构严蔚敏PPT数据结构严蔚敏PPT(2) Huffman树的生成树的生成算法实现算法实现void Create_Huffman(unsigned n, HTNode HT , unsigned

408、 m) /* 创建一棵叶子结点数为创建一棵叶子结点数为n的的Huffman树树 */ unsigned int w ; int k , j ;for (k=1 ; km ; k+) if (k=n) printf(“n Please Input Weight : w=?”); scanf(“%d”, &w) ;HTk.weight=w ; /* 输入时输入时,所有叶子结点都有权值所有叶子结点都有权值 */else HTk.weight=0; /* 非叶子结点没有权值非叶子结点没有权值 */佯藐汀覆而校忠辩狂喀酱孟蒋恐凝赢漫棕搞依随话癣芦编俞呀跑尽磷容时数据结构严蔚敏PPT数据结构严蔚敏PPTH

409、Tk.Parent=HTk.Lchild=HTk.Rchild=0 ; /* 初始化向量初始化向量HT */for (k=n+1; km ; k+) unsigned w1=32767 , w2=w1 ; /* w1 , w2分别保存权值最小的两个权值分别保存权值最小的两个权值 */ int p1=0 , p2=0 ; /* p1 , p2保存两个最小权值的下标保存两个最小权值的下标 */for (j=1 ; j=k-1 ; j+) if (HTk.Parent=0) /* 尚未合并尚未合并 */ if (HTj.Weightw1) w2=w1 ; p2=p1 ; w1=HTj.Weight

410、; p1=j ; 侧泣湃培爪举跃煽嘶硼床化铝旱夯庭铂窗滦瀑党穗狰胎粳涌搭豺科某犊冷数据结构严蔚敏PPT数据结构严蔚敏PPT else if (HTj.Weightw2) w2=HTj.Weight ; p2=j ; /* 找到权值最小的两个值及其下标找到权值最小的两个值及其下标 */HTk.Lchild=p1 ; HTk.Rchild=p2 ;HTk.weight=w1+w2 ;HTp1.Parent=k ; HTp2.Parent=k ; 说明说明:生成生成Huffman树后,树的根结点的下标是树后,树的根结点的下标是2n-1 ,即,即m-1 。伎年竿也贴迢眯褂沙耶咳崭卜膝懊另宵纶励洋轰劝疮

411、倔符泣潞仅亢厅隧妨数据结构严蔚敏PPT数据结构严蔚敏PPT(3) Huffman编码算法编码算法 根据出现频度根据出现频度( (权值权值) )Weight,对叶子结点的对叶子结点的Huffman编码有两种方式编码有两种方式: 从叶子结点到根逆向处理,求得每个叶子结点对从叶子结点到根逆向处理,求得每个叶子结点对应字符的应字符的Huffman编码。编码。 从根结点开始遍历整棵二叉树,求得每个叶子结从根结点开始遍历整棵二叉树,求得每个叶子结点对应字符的点对应字符的Huffman编码。编码。 由由Huffman树的生成知,树的生成知,n个叶子结点的树共有个叶子结点的树共有2n-1个结点,叶子结点存储在

412、数组个结点,叶子结点存储在数组HT中的下标值为中的下标值为1n。 编码是叶子结点的编码,只需对数组编码是叶子结点的编码,只需对数组HT1n的的n个权值进行编码;个权值进行编码; 每个字符的编码不同,但编码的最大长度是每个字符的编码不同,但编码的最大长度是n。孽匆臂碘君舆嘘钓姻窑刑疽烧弓蛤肥殴实别颜洋韧窟迟淀搓债钮刨油俊孟数据结构严蔚敏PPT数据结构严蔚敏PPT 求编码时先设一个通用的指向字符的指针变量,求求编码时先设一个通用的指向字符的指针变量,求得编码后再复制。得编码后再复制。算法实现算法实现void Huff_coding(unsigned n , Hnode HT , unsigned

413、m) /* m应为应为n+1,编码的最大长度编码的最大长度n加加1 */ int k , sp ,fp ;char *cd , *HCm ;cd=(char *)malloc(m*sizeof(char) ;/* 动态分配求编码的工作空间动态分配求编码的工作空间 */cdn=0 /* 编码的结束标志编码的结束标志 */for (k=1 ; kn+1 ; k+) /* 逐个求字符的编码逐个求字符的编码 */ sp=n ; p=k ; fp=HTk.parent ; 惺翟戴樱簿给殷迭论啄纹闷腾噬置额揩所庞么渊疼遮粪脉拌皑推真蜒禾测数据结构严蔚敏PPT数据结构严蔚敏PPTfor ( ; fp!=0

414、;p=fp , fp=HTp.parent) /* 从叶子结点到根逆向求编码从叶子结点到根逆向求编码 */ if (HTfp.parent=p) cd-sp=0 ; else cd-sp=1 ;HCk=(char *)malloc(n-sp)*sizeof(char) ; /* 为第为第k个字符分配保存编码的空间个字符分配保存编码的空间 */trcpy(HCk , &cdsp) ;free(cd) ;蹬喷反柳惦冕梭芦窿芝厩芯炕诅帖痔埃糜呈鹿篓却钎抬轰掣芒芥频诀皋覆数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 六六 假设在树中,假设在树中, 结点结点x是结点是结点y的双亲时,用的双亲时,用

415、(x,y)来来表示树边。已知一棵树的树边集合为表示树边。已知一棵树的树边集合为 (e,i), (b,e), (b,d), (a,b), (g,j), (c,g), (c,f), (h,l), (c,h), (a,c) ,用树型表示法表示该树,并回答下列问题:,用树型表示法表示该树,并回答下列问题: 哪个是根结点哪个是根结点? 哪些是叶子结点哪些是叶子结点? 哪个是哪个是g的双的双亲亲? 哪些是哪些是g的祖先的祖先? 哪些是哪些是g的孩子的孩子? 那些是那些是e的子的子孙孙? 哪些是哪些是e的兄弟的兄弟? 哪些是哪些是f的兄弟的兄弟? b和和n的层次各是多少的层次各是多少? 树的深度是多少树的深

416、度是多少? 以结以结点点c为根的子树的深度是多少为根的子树的深度是多少?癣兽盔饼陪腔馅汤器凝逾帧随竹舱膘疑咀睛肆霜碗昆助膜炯刀籍侧洲直渣数据结构严蔚敏PPT数据结构严蔚敏PPT 一棵深度为一棵深度为h的满的满k叉树有如下性质:叉树有如下性质: 第第h层上的层上的结点都是叶子结点,其余各层上每个结点都有结点都是叶子结点,其余各层上每个结点都有k棵非空棵非空子树。子树。 如果按层次顺序如果按层次顺序(同层自左至右同层自左至右)从从1开始对全部开始对全部结点编号,问:结点编号,问: 各层的结点数是多少各层的结点数是多少? ? 编号为编号为i的结点的双亲结点的结点的双亲结点(若存在若存在)的编号是多的

417、编号是多少少? 编号为编号为i的结点的第的结点的第j个孩子结点个孩子结点(若存在若存在)的编号的编号是多少是多少? 编号为编号为i的结点的有右兄弟的条件是什么的结点的有右兄弟的条件是什么? 其右其右兄弟的编号是多少兄弟的编号是多少? 赎缆巩中贡缄直禽希荆歌瘦刀拟尝啃疯递少堂绸丙找遏晨银氧熙搓耿裙蓝数据结构严蔚敏PPT数据结构严蔚敏PPT 设有如图设有如图6-27所示的二叉树。所示的二叉树。 分别用顺序存储方法和链接存储方法画出该二分别用顺序存储方法和链接存储方法画出该二叉树的存储结构。叉树的存储结构。 写出该二叉树的先序、中序、后序遍历序列。写出该二叉树的先序、中序、后序遍历序列。 已知一棵二

418、叉树的先序遍历序列和中序遍历序列已知一棵二叉树的先序遍历序列和中序遍历序列分别为分别为ABDGHCEFI和和GDHBAECIF,请画出这棵二叉,请画出这棵二叉树,然后给出该树的后序遍历序列。树,然后给出该树的后序遍历序列。 设一棵二叉树的中序遍历序列设一棵二叉树的中序遍历序列和后序遍历序列分别为和后序遍历序列分别为BDCEAFHG和和DECBHGFA ,请画出这棵二叉树,请画出这棵二叉树,然后给出该树的先序序列。然后给出该树的先序序列。图图6-27 二叉树二叉树adebfgchkmn想却兵安箭樟蹄藤曹乳邓嘶椎篷锯皖令董喳寻坚蕊秩菲曹铸瘦沉纯胳喇雄数据结构严蔚敏PPT数据结构严蔚敏PPT 已知一

419、棵二叉树的中序遍历序列和后序遍历序列已知一棵二叉树的中序遍历序列和后序遍历序列分别为分别为dgbaekchif和和gdbkeihfca,请画出这棵二叉树对,请画出这棵二叉树对应的中序线索树和后序线索树。应的中序线索树和后序线索树。 以二叉链表为存储结构,请分别写出求二叉树的以二叉链表为存储结构,请分别写出求二叉树的结点总数及叶子结点总数的算法。结点总数及叶子结点总数的算法。 设设图图6-27所示的二叉树是森林所示的二叉树是森林F所对应的二叉树,所对应的二叉树,请画出森林请画出森林F。 设有一棵树,如图设有一棵树,如图6-28所示。所示。 请分别用双亲表示法请分别用双亲表示法、孩子表示法孩子表示

420、法、孩子兄弟孩子兄弟表示法给出该树的存储结构。表示法给出该树的存储结构。 请给出该树的先序遍历序列和后序遍历序列。请给出该树的先序遍历序列和后序遍历序列。 请将这棵树转换成二叉树。请将这棵树转换成二叉树。宫郁抛湿鲜撂佯街爆湘丸俄皖辟亭伪引穷慕椅竹返粉墓拜位鲸油蜘典屁捐数据结构严蔚敏PPT数据结构严蔚敏PPT 设给定权值集合设给定权值集合w=3,5,7,8,11,12 ,请构造关于,请构造关于w的一棵的一棵huffman树,并求其加权路径长度树,并求其加权路径长度WPL 。 假设用于通信的电文是由字符集假设用于通信的电文是由字符集a, b, c, d, e, f, g, h中的字符构成中的字符构

421、成, 这这8个字符在电文中出现的概率分别个字符在电文中出现的概率分别为为0.07, 0.19, 0.02, 0.06, 0.32, 0.03, 0.21, 0.10 。 请画出对应的请画出对应的huffman树树( (按左子树根结点的权按左子树根结点的权小于等于右子树根结点的权的次序构造小于等于右子树根结点的权的次序构造) )。 求出每个字符的求出每个字符的huffman编码。编码。adebfgmh kcn图图6-28 一般的树一般的树撕丘瓜卞航象曲痊奸仟和嘘船疑懂蒸纳镊鞭靶趣哎肌浴垄筷霉玫蚂铜融片数据结构严蔚敏PPT数据结构严蔚敏PPT第第7章章 图图 图图(Graph)是一种比线性表和树更

422、为复杂的数据结是一种比线性表和树更为复杂的数据结构。构。 线性结构线性结构:是研究数据元素之间的一对一关系。是研究数据元素之间的一对一关系。在这种结构中,除第一个和最后一个元素外,任何一个在这种结构中,除第一个和最后一个元素外,任何一个元素都有唯一的一个直接前驱和直接后继。元素都有唯一的一个直接前驱和直接后继。 树结构树结构:是研究数据元素之间的一对多的关系。是研究数据元素之间的一对多的关系。在这种结构中,每个元素对下在这种结构中,每个元素对下(层层)可以有可以有0个或多个元个或多个元素相联系,对上素相联系,对上(层层)只有唯一的一个元素相关,数据元只有唯一的一个元素相关,数据元素之间有明显的

423、层次关系。素之间有明显的层次关系。爵井菱尺惟枚玛茅蛤之童栏站露泽誉卖是设情真芭喂梧睫澡缮康矛番跪腕数据结构严蔚敏PPT数据结构严蔚敏PPT 图结构图结构:是研究数据元素之间的多对多的关系。是研究数据元素之间的多对多的关系。在这种结构中,任意两个元素之间可能存在关系。即结在这种结构中,任意两个元素之间可能存在关系。即结点之间的关系可以是任意的,图中任意元素之间都可能点之间的关系可以是任意的,图中任意元素之间都可能相关。相关。 图的应用极为广泛,已渗入到诸如语言学、逻辑学、图的应用极为广泛,已渗入到诸如语言学、逻辑学、物理、化学、电讯、计算机科学以及数学的其它分支。物理、化学、电讯、计算机科学以及

424、数学的其它分支。赶沃揣绿徊浮担冕齐庸脂饯乃招铺纽篆逗帽乒匪绿改程尚剖治冤朵厕碟宇数据结构严蔚敏PPT数据结构严蔚敏PPT7.1 图的基本概念图的基本概念7.1.1 图的定义和术语图的定义和术语 一个图一个图(G)定义为一个偶对定义为一个偶对(V,E) ,记为,记为G=(V,E) 。其中:其中: V是是顶点顶点(Vertex)的非空有限集合,记为的非空有限集合,记为V(G);E是无序集是无序集V&V的一个子集,记为的一个子集,记为E(G) ,其元素是图的,其元素是图的弧弧(Arc)。 将顶点集合为空的图称为空图。其形式化定义为:将顶点集合为空的图称为空图。其形式化定义为:G=(V ,E)V=v|

425、v data objectE=| v,w Vp(v,w)P(v,w)表示从顶点表示从顶点v到顶点到顶点w有一条直接通路。有一条直接通路。莎褒业纺管惨属循咎姚营承龚搓傣蹈戚笑惊热疾咐琅梁峪贿筹沼残烷辞壕数据结构严蔚敏PPT数据结构严蔚敏PPT 弧弧(Arc) :表示两个顶点表示两个顶点v和和w之间存在一个关系,之间存在一个关系,用顶点偶对用顶点偶对表示。通常根据图的顶点偶对将图分表示。通常根据图的顶点偶对将图分为有向图和无向图。为有向图和无向图。 有向图有向图(Digraph): 若图若图G的关系集合的关系集合E(G)中,中,顶点偶对顶点偶对的的v和和w之间是之间是有序有序的,称图的,称图G是有

426、向图。是有向图。 在有向图中,若在有向图中,若 E(G) ,表示从顶点,表示从顶点v到顶点到顶点w有一条有一条弧弧。 其中:其中:v称为称为弧尾弧尾(tail)或或始点始点(initial node),w称为称为弧头弧头(head)或或终点终点(terminal node) 。 无向图无向图(Undigraph): 若图若图G的关系集合的关系集合E(G)中,中,顶点偶对顶点偶对的的v和和w之间是之间是无序无序的,称图的,称图G是无向图。是无向图。 捻症查喂宜豌予绸绅硬人朵毯嘴撅荐贼掩廊番叮雄吹山留倒抹衰筛检削裕数据结构严蔚敏PPT数据结构严蔚敏PPT 在无向图中,若在无向图中,若 E(G) ,

427、有,有 E(G) ,即即E(G)是对称,则用无序对是对称,则用无序对(v,w) 表示表示v和和w之间的一条之间的一条边边(Edge),因此,因此(v,w) 和和(w,v)代表的是同一条边。代表的是同一条边。例例1:设有有向图:设有有向图G1和无向图和无向图G2,形式化定义分别是:,形式化定义分别是:G1=(V1 ,E1)V1=a,b,c,d,eE1=, , ,G2=(V2 ,E2)V2=a,b,c,dE2=(a,b), (a,c), (a,d), (b,d), (b,c), (c,d)它们所对应的图如图它们所对应的图如图7-1所示。所示。殿稀胀恋书百捎任柔捞苔筐戈职雌礁搓没凛葵瘤如博阔身珐檬绩

428、六携暮垂数据结构严蔚敏PPT数据结构严蔚敏PPT 完全无向图完全无向图:对于无向图,若图中顶点数为对于无向图,若图中顶点数为n ,用用e表示边的数目,则表示边的数目,则e 0,n(n-1)/2 。具有。具有n(n-1)/2条条边的无向图称为完全无向图。边的无向图称为完全无向图。完全无向图另外的定义是:完全无向图另外的定义是: 对于无向图对于无向图G=(V,E),若,若 vi,vj V ,当,当vivj时,时,有有(vi ,vj) E,即,即图中任意两个不同的顶点间都有一条图中任意两个不同的顶点间都有一条无向边无向边,这样的无向图称为,这样的无向图称为完全无向图完全无向图。abcd(b) 无向图

429、无向图G2 图图7-1 图的示例图的示例(a) 有向图有向图G1 acbde灵民部昌继半凛溪抉偶腹梧缕椅讯帘新技仍簿纬希酪呻垛限晚卑办哭轮胆数据结构严蔚敏PPT数据结构严蔚敏PPT 完全有向图完全有向图:对于有向图,若图中顶点数为对于有向图,若图中顶点数为n ,用用e表示弧的数目,则表示弧的数目,则e 0,n(n-1) 。具有。具有n(n-1)条边条边的有向图称为完全有向图。的有向图称为完全有向图。完全有向图另外的定义是:完全有向图另外的定义是: 对于有向图对于有向图G=(V,E),若,若 vi,vj V ,当,当vi vj时,时,有有 E E ,即,即图中任意两个不同的顶图中任意两个不同的顶

430、点间都有一条弧点间都有一条弧,这样的有向图称为,这样的有向图称为完全有向图完全有向图。 有很少边或弧的图(有很少边或弧的图(enn)的图称为)的图称为稀疏图稀疏图,反,反之称为之称为稠密图稠密图。权权(Weight):与图的边和弧相关的数。权可以表示从与图的边和弧相关的数。权可以表示从一个顶点到另一个顶点的距离或耗费。一个顶点到另一个顶点的距离或耗费。梆砖枷妙系牛缅壶桅籍陵窿集豁灯巡贬白旁逻跟乙弧嘶盘忧埂煞馈习膏似数据结构严蔚敏PPT数据结构严蔚敏PPT 子图和生成子图子图和生成子图:设有图设有图G=(V,E)和和G=(V,E),若,若V V且且E E ,则称图,则称图G是是G的的子图子图;若

431、;若V=V且且E E,则称图,则称图G是是G的一个的一个生成子图生成子图。 顶点的邻接顶点的邻接(Adjacent):对于无向图对于无向图G=(V,E),若边,若边(v,w) E,则称顶点,则称顶点v和和w 互为互为邻接点邻接点,即,即v和和w相邻接。边相邻接。边(v,w)依附依附(incident)与顶点与顶点v和和w 。 对于有向图对于有向图G=(V ,E),若有向弧,若有向弧 E,则称,则称顶点顶点v “邻接到邻接到”顶点顶点w,顶点,顶点w “邻接自邻接自”顶点顶点v ,弧,弧 与顶点与顶点v和和w “相关联相关联” 。 顶点的度、入度、出度顶点的度、入度、出度:对于无向图对于无向图G

432、=(V,E), vi V,图,图G中中依附依附于于vi的边的数目称为顶点的边的数目称为顶点vi的的度度(degree),记为,记为TD(vi)。玖诅袜康寝障挣探漫亨纳榨查队尉乱禾而滨乞策胸伯佳煌硕馈御励旺鸟禄数据结构严蔚敏PPT数据结构严蔚敏PPT 显然,在无向图中,所有顶点度的和是图中边的显然,在无向图中,所有顶点度的和是图中边的2倍。倍。 即即 TD(vi)=2e i=1, 2, , n ,e为图的边数。为图的边数。 对有向图对有向图G=(V,E),若,若 vi V ,图,图G中中以以vi作为起作为起点点的有向边的有向边(弧弧)的数目称为顶点的数目称为顶点vi的的出度出度(Outdegre

433、e),记为记为OD(vi) ;以以vi作为终点作为终点的有向边的有向边(弧弧)的数目称为顶的数目称为顶点点vi的的入度入度(Indegree),记为,记为ID(vi) 。顶点。顶点vi的的出度出度与与入入度度之和称为之和称为vi的的度度,记为,记为TD(vi) 。即。即TD(vi)=OD(vi)+ID(vi) 路径路径(Path)、路径长度、回路、路径长度、回路(Cycle) :对无对无向图向图G=(V,E),若从顶点,若从顶点vi经过若干条边能到达经过若干条边能到达vj,称,称顶点顶点vi和和vj是是连通连通的,又称顶点的,又称顶点vi到到vj有有路径路径。 对有向图对有向图G=(V,E),

434、从顶点,从顶点vi到到vj有有有向路径有向路径,指,指的是从顶点的是从顶点vi经过若干条有向边经过若干条有向边(弧弧)能到达能到达vj。盖固碗褐疗锐攘遵罗菇榷垂谴莫顿敬赣窟责蜗翻息浚溅诛民券庶稽佑罕里数据结构严蔚敏PPT数据结构严蔚敏PPT 或或路径路径是图是图G中连接两顶点之间所经过的顶点序列。中连接两顶点之间所经过的顶点序列。即即 Path=vi0vi1vim ,vij V且且(vij-1, vij) E j=1,2, ,m或或 Path=vi0vi1 vim ,vij V且且 E j=1,2, ,m 路径上边或有向边路径上边或有向边(弧弧)的数目称为该的数目称为该路径路径的的长度长度。

435、在一条路径中,若在一条路径中,若没有重复相同没有重复相同的顶点,该路径称的顶点,该路径称为为简单路径简单路径;第一个顶点和最后一个顶点相同的路径称;第一个顶点和最后一个顶点相同的路径称为为回路回路(环环);在一个回路中,若除第一个与最后一个顶;在一个回路中,若除第一个与最后一个顶点外,其余顶点不重复出现的回路称为点外,其余顶点不重复出现的回路称为简单回路简单回路(简单简单环环)。逼骚志鬃隅次莲抑犹悼葱铅胰岿侄耿帖筑抗窜洋竹背疟淳熟暴逃凶冈咋蛇数据结构严蔚敏PPT数据结构严蔚敏PPT 连通图、图的连通分量连通图、图的连通分量:对无向图对无向图G=(V,E),若若 vi ,vj V,vi和和vj都

436、是连通的,则称图都是连通的,则称图G是是连通图连通图,否则称为否则称为非连通图非连通图。若。若G是非连通图,则是非连通图,则极大的连通子极大的连通子图图称为称为G的的连通分量连通分量。 对有向图对有向图G=(V,E),若,若 vi ,vj V,都有,都有以以vi为起为起点点, vj 为终点为终点以及以以及以vj为起点,为起点,vi为终点的有向路径,为终点的有向路径,称图称图G是是强连通图强连通图,否则称为,否则称为非强连通图非强连通图。若。若G是非强是非强连通图,则连通图,则极大的强连通子图极大的强连通子图称为称为G的的强连通分量强连通分量。 “极大极大”的含义:指的是对子图再增加图的含义:指

437、的是对子图再增加图G中的其它中的其它顶点,子图就不再连通。顶点,子图就不再连通。抹瓮凋汾狙枚沛班映艳粕踪股冯舱岁菇禁璃狈单裂窍唉朴舒羹椽抄广逝旗数据结构严蔚敏PPT数据结构严蔚敏PPT 生成树、生成森林生成树、生成森林:一个连通图一个连通图(无向图无向图)的生成的生成树是一个极小连通子图,它树是一个极小连通子图,它含有图中全部含有图中全部n个顶点个顶点和只和只有足以构成一棵树的有足以构成一棵树的n-1条边条边,称为图的,称为图的生成树生成树,如图,如图7-2所示。所示。 关于无向图的生成树的几个结论:关于无向图的生成树的几个结论: 一棵有一棵有n个顶点的生成树有且仅有个顶点的生成树有且仅有n-

438、1条边;条边; 如果一个图有如果一个图有n个顶点和小于个顶点和小于n-1条边,则是非连条边,则是非连通图;通图;adbc图图7-2 图图G2的一棵生成树的一棵生成树 如果多于如果多于n-1条边,则一定条边,则一定有环;有环; 有有n-1条边的图不一定是生条边的图不一定是生成树。成树。袖椎昆鬼顿叛姿辨拉秆愈品贩医牙棋密腆拈恃获芹伦蹿诚挥顶择剁卑幅诸数据结构严蔚敏PPT数据结构严蔚敏PPT 有向图的有向图的生成森林生成森林是这样一个子图,由若干棵是这样一个子图,由若干棵有向有向树树组成,含有图中全部顶点。组成,含有图中全部顶点。有向树有向树是只有一个顶点的入度为是只有一个顶点的入度为0 ,其余顶点

439、的入度均,其余顶点的入度均为为1的有向图,如图的有向图,如图7-3所示。所示。 网网:每个边每个边(或弧或弧)都附加一个权值的图,称为都附加一个权值的图,称为带权带权图图。带权的连通图带权的连通图(包括弱连通的有向图包括弱连通的有向图)称为称为网或网络网或网络。网络是工程上常用的一个概念,用来表示一个工程或某网络是工程上常用的一个概念,用来表示一个工程或某种流程,如图种流程,如图7-4所示。所示。图图7-3 有向图及其生成森林有向图及其生成森林abcdedce(a) 有向图有向图(b) 生成森林生成森林acbcb354126abcde3图图7-4 带权有向图带权有向图彪绷习罐免工岿羡倒噶保剖甜

440、惕拖搅隅沁砰养很餐畜玫秩摈蛙稀官萨镣札数据结构严蔚敏PPT数据结构严蔚敏PPT7.1.2 图的抽象数据类型定义图的抽象数据类型定义 图是一种数据结构图是一种数据结构,加上一组基本操作就构成了图加上一组基本操作就构成了图的抽象数据类型的抽象数据类型。图的抽象数据类型定义如下:图的抽象数据类型定义如下:ADT Graph数据对象数据对象V:具有相同特性的数据元素的集合:具有相同特性的数据元素的集合,称为称为顶点集顶点集。数据关系数据关系R:R=VRVR=| v,w Vp(v,w) ,表示表示 从从v到到w的弧,的弧,P(v,w)定义了弧定义了弧的信息的信息 倔帝精猜篮橙蜘蕊拘暇氯雀肿六吊藐抬殆婉茵

441、洁锰琶碑祖气粟霹乎书爽敢数据结构严蔚敏PPT数据结构严蔚敏PPT基本操作基本操作P: Create_Graph() : 图的创建操作图的创建操作。初始条件:无。初始条件:无。 操作结果:生成一个没有顶点的空图操作结果:生成一个没有顶点的空图G。GetVex(G, v) : 求图中的顶点求图中的顶点v的值。的值。初始条件:图初始条件:图G存在,存在,v是图中的一个顶点。是图中的一个顶点。操作结果:生成一个没有顶点的空图操作结果:生成一个没有顶点的空图G。 DFStraver(G,V):从:从v出发对图出发对图G深度优先遍历。深度优先遍历。 初始条件:图初始条件:图G存在。存在。 操作结果:对图操

442、作结果:对图G深度优先遍历,每个顶点访问深度优先遍历,每个顶点访问且只访问一次。且只访问一次。暇迢粥葱戍珠辕藤苹置街唱疟孙俯兜曼朔尸方帅绘设蔼伐钙娥返岗倦赘恢数据结构严蔚敏PPT数据结构严蔚敏PPT BFStraver(G,V):从:从v出发对图出发对图G广度优先遍历。广度优先遍历。 初始条件:图初始条件:图G存在。存在。 操作结果:对图操作结果:对图G广度优先遍历,每个顶点访问广度优先遍历,每个顶点访问且只访问一次。且只访问一次。 ADT Graph 详见详见p156157。乡贱峦稚催斯宦麻蹲莎诣糙咸挨文记武拄娄射酬幌而振敦汕犬耍蒜丁脉隋数据结构严蔚敏PPT数据结构严蔚敏PPT7.2 图的存

443、储结构图的存储结构 图的存储结构比较复杂,其复杂性主要表现在:图的存储结构比较复杂,其复杂性主要表现在: 任意顶点之间可能存在联系,无法以数据元素任意顶点之间可能存在联系,无法以数据元素在存储区中的物理位置来表示元素之间的关系。在存储区中的物理位置来表示元素之间的关系。 图中顶点的度不一样,有的可能相差很大,若图中顶点的度不一样,有的可能相差很大,若按度数最大的顶点设计结构,则会浪费很多存储单按度数最大的顶点设计结构,则会浪费很多存储单元,反之按每个顶点自己的度设计不同的结构,又元,反之按每个顶点自己的度设计不同的结构,又会影响操作。会影响操作。 图的常用的存储结构有:图的常用的存储结构有:邻

444、接矩阵邻接矩阵、邻接链表邻接链表、十十字链表字链表、邻接多重表邻接多重表和和边表边表。净弥雷吉狰博抡埋虐盈王羡傍疯盂翰持掉谅伦河箩迟骗咕禄耙资皿磐空缚数据结构严蔚敏PPT数据结构严蔚敏PPT7.2.1 邻接矩阵邻接矩阵(数组数组)表示法表示法 基本思想基本思想:对于有对于有n个顶点的图,用一维数组个顶点的图,用一维数组vexsn存储顶点信息,用二维数组存储顶点信息,用二维数组Ann存储顶点之间存储顶点之间关系的信息。该二维数组称为关系的信息。该二维数组称为邻接矩阵邻接矩阵。在邻接矩阵中,。在邻接矩阵中,以顶点在以顶点在vexs数组中的下标代表顶点,邻接矩阵中的元数组中的下标代表顶点,邻接矩阵中

445、的元素素Aij存放的是顶点存放的是顶点i到顶点到顶点j之间关系的信息。之间关系的信息。黍尊乐辣叹拥联湃睛淖洱蹲青空旋枫疆岸冗锑蛹沏设迸江淳臂夺饲肩厄炬数据结构严蔚敏PPT数据结构严蔚敏PPT1 无向图的数组表示无向图的数组表示(1) 无权图的邻接矩阵无权图的邻接矩阵 无向无权图无向无权图G=(V,E)有有n(n1)个顶点,其邻接矩个顶点,其邻接矩阵是阵是n阶对称方阵,如图阶对称方阵,如图7-5所示。其元素的定义如下:所示。其元素的定义如下:1 若若(vi , vj) E,即,即vi , vj邻接邻接0 若若(vi , vj) E,即,即vi , vj不邻接不邻接Aij=(a) 无向图无向图 a

446、bcd图图7-5 无向无权图的数组存储无向无权图的数组存储(b) 顶点矩阵顶点矩阵vexsabcd0 1 1 11 0 1 11 1 0 11 1 1 0(c) 邻接矩阵邻接矩阵幢蛹辰秀撅笋浪疹伞膏芋抒掷懦钧蘑诊翘渔讥脚执站环猛嘲梳曳谋肩乌脚数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 带权图的邻接矩阵带权图的邻接矩阵 无向带权图无向带权图G=(V,E) 的邻接矩阵如图的邻接矩阵如图7-6所示。其所示。其元素的定义如下:元素的定义如下:(a) 带权无向图带权无向图 (b) 顶点矩阵顶点矩阵图图7-6 无向带权图的数组存储无向带权图的数组存储(c) 邻接矩阵邻接矩阵354126abcde3ve

447、xsabcde 6 2 6 3 4 32 3 1 4 3 5 3 5 Wij 若若(vi , vj) E,即,即vi , vj邻接,权值为邻接,权值为wij 若若(vi , vj) E,即,即vi , vj不邻接时不邻接时Aij=洁罩彝睁税疚蕴线布腆伊痉桌帚勒讳敝腋裤俊懦孪矫渐窟送犹琵坚茄姆卯数据结构严蔚敏PPT数据结构严蔚敏PPT(3) 无向图邻接矩阵的特性无向图邻接矩阵的特性 邻接矩阵是邻接矩阵是对称方阵对称方阵; 对于顶点对于顶点vi,其,其度数度数是第是第i行的非行的非0元素的个数;元素的个数; 无向图的无向图的边数边数是上是上(或下或下)三角形矩阵中非三角形矩阵中非0元素元素个数。个

448、数。2 有向图的数组表示有向图的数组表示(1) 无权图的邻接矩阵无权图的邻接矩阵 若有向无权图若有向无权图G=(V,E)有有n(n1)个顶点,则其邻个顶点,则其邻接矩阵是接矩阵是n阶对称方阵阶对称方阵,如图,如图7-7所示。元素定义如下:所示。元素定义如下:1 若若 E,从,从vi到到vj有弧有弧Aij=0 若若 E 从从vi到到vj 没有弧没有弧榆亮且宦糟竭域在镑艰异炎濒蔗打媒炭肉正埋坷票打此淆秘藻酣序尖琴攻数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 有向图有向图acbde图图7-7 有向无权图的数组存储有向无权图的数组存储(b) 顶点矩阵顶点矩阵vexsabcde(c) 邻接矩阵邻接矩

449、阵0 1 1 0 10 0 0 0 00 0 0 1 11 1 0 0 00 0 0 1 0(2) 带权图的邻接矩阵带权图的邻接矩阵 有向带权图有向带权图G=(V,E)的邻接矩阵如图的邻接矩阵如图7-8所示。其所示。其元素的定义如下:元素的定义如下:wij 若若 E,即,即vi , vj邻接,权值为邻接,权值为wij 若若 E,即,即vi , vj不邻接时不邻接时Aij=弗终沟摔滤坑罐卤衔原况魁灿应绥洪逞支栽钢凰堤藉旬拉垣双式庶匿价俱数据结构严蔚敏PPT数据结构严蔚敏PPT图图7-8 带权有向图的数组存储带权有向图的数组存储(b) 顶点矩阵顶点矩阵vexsabcde(c) 邻接矩阵邻接矩阵 6

450、 2 3 3 1 4 5 (a) 带权有向图带权有向图 354126abcde3 有向图邻接矩阵的特性有向图邻接矩阵的特性 对于顶点对于顶点vi,第,第i行的非行的非0元素的个数是其元素的个数是其出度出度OD(vi);第;第i列的非列的非0元素的个数是其元素的个数是其入度入度ID(vi) 。 邻接矩阵中非邻接矩阵中非0元素的个数就是图的弧的数目。元素的个数就是图的弧的数目。汾龄伺悍焕痒削煽绥收询滁堰励毕灌橙哄画隆亦崖荤逆疾敝朱窑盘遥卓戈数据结构严蔚敏PPT数据结构严蔚敏PPT3 图的邻接矩阵的操作图的邻接矩阵的操作 图的邻接矩阵的实现比较容易,定义两个数组分别图的邻接矩阵的实现比较容易,定义两

451、个数组分别存储存储顶点信息顶点信息(数据元素数据元素)和和边或弧的信息边或弧的信息(数据元素之数据元素之间的关系间的关系) 。其。其存储结构形式定义存储结构形式定义如下:如下:#define INFINITY MAX_VAL /* 最大值最大值 */ /* 根据图的权值类型,分别定义为最大整数或实数根据图的权值类型,分别定义为最大整数或实数 */#define MAX_VEX 30 /* 最大顶点数目最大顶点数目 */typedef enum DG, AG, WDG,WAG GraphKind ; /* 有向图,无向图,带权有向图,带权无向图有向图,无向图,带权有向图,带权无向图 */朝衙树闭

452、晦税间霜颠锐锣碳哦奉喝把娄涵辕称短唤翠晚祥涌土记劣腥痛简数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct ArcType VexType vex1, vex2 ; /* 弧或边所依附的两个顶点弧或边所依附的两个顶点 */ArcValType ArcVal ; /* 弧或边的权值弧或边的权值 */ArcInfoType ArcInfo ; /* 弧或边的其它信息弧或边的其它信息 */ArcType ; /* 弧或边的结构定义弧或边的结构定义 */typedef struct GraphKind kind ; /* 图的种类标志图的种类标志 */int vexnum , arc

453、num ; /* 图的当前顶点数和弧数图的当前顶点数和弧数 */VexType vexsMAX_VEX ; /* 顶点向量顶点向量 */AdjType adjMAX_VEXMAX_VEX;MGraph ; /* 图的结构定义图的结构定义 */刹斯琳俘拼恕廊凤哪蔽赔犀婉棠竭竖肚树蓖径泅鸵示阿浸月俄进空呢央肾数据结构严蔚敏PPT数据结构严蔚敏PPT 利用上述定义的数据结构,可以方便地实现图的各利用上述定义的数据结构,可以方便地实现图的各种操作。种操作。(1) 图的创建图的创建AdjGraph *Create_Graph(MGraph * G) printf(“请输入图的种类标志:请输入图的种类标志

454、:”) ;scanf(“%d”, &G-kind) ;G-vexnum=0 ; /* 初始化顶点个数初始化顶点个数 */return(G) ; 喷瑶凸校邦榆止律砚绷途狭叉奶株倦吼遵垄酣肤搅糟篆敞童谓兜窒寓屠捕数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 图的顶点定位图的顶点定位 图的顶点定位操作实际上是确定一个顶点在图的顶点定位操作实际上是确定一个顶点在vexs数数组中的位置组中的位置(下标下标) ,其过程完全等同于在顺序存储的线,其过程完全等同于在顺序存储的线性表中查找一个数据元素。性表中查找一个数据元素。算法实现算法实现:int LocateVex(MGraph *G , VexType

455、 *vp) int k ; for (k=0 ; kvexnum ; k+) if (G-vexsk=*vp) return(k) ; return(-1) ; /* 图中无此顶点图中无此顶点 */ 联揩褐诸龙恶质撩闻爵钡柄碎正掣金鞋宇襟乙戴晚到寡舱郝植范踩料升捅数据结构严蔚敏PPT数据结构严蔚敏PPT(3) 向图中增加顶点向图中增加顶点 向图中增加一个顶点的操作,类似在顺序存储的线向图中增加一个顶点的操作,类似在顺序存储的线性表的末尾增加一个数据元素。性表的末尾增加一个数据元素。算法实现算法实现:int AddVertex(MGraph *G , VexType *vp) int k , j

456、 ;if (G-vexnum=MAX_VEX) printf(“Vertex Overflow !n”) ; return(-1) ; if (LocateVex(G , vp)!=-1) printf(“Vertex has existed !n”) ; return(-1) ; k=G-vexnum ; G-vexsG-vexnum+=*vp ;染别刨斌鸟汐玫心娜杂坐虞者析撩蝇吩革黄痔拍勋括宛圈执渤粉疗贼循廉数据结构严蔚敏PPT数据结构严蔚敏PPTif (G-kind=DG|G-kind=AG) for (j=0 ; jvexnum ; j+)G-adjjk.ArcVal=G-adjkj.

457、ArcVal=0 ; /* 是不带权的有向图或无向图是不带权的有向图或无向图 */elsefor (j=0 ; jvexnum ; j+) G-adjjk.ArcVal=INFINITY ; G-adjkj.ArcVal=INFINITY ; /* 是带权的有向图或无向图是带权的有向图或无向图 */return(k) ;洲争包超撂佰甸柜睁慌酷昌咀荔茅绕这电鹅演竹乌氛棉鼎著绚突蛆粕频擅数据结构严蔚敏PPT数据结构严蔚敏PPT(4) 向图中增加一条弧向图中增加一条弧 根据给定的弧或边所依附的顶点,修改邻接矩阵中根据给定的弧或边所依附的顶点,修改邻接矩阵中所对应的数组元素。所对应的数组元素。算法实现

458、算法实现: int AddArc(MGraph *G , ArcType *arc) int k , j ;k=LocateVex(G , &arc-vex1) ;j=LocateVex(G , &arc-vex1) ;if (k=-1|j=-1) printf(“Arcs Vertex do not existed !n”) ;return(-1) ;掩耸韧态齿猎运享崇躺滇契烛兜骨虫钙巫鹰贬撅掖瘸井电巾贸汞碴描嘉舆数据结构严蔚敏PPT数据结构严蔚敏PPTif (G-kind=DG|G-kind=WDG) G-adjkj.ArcVal=arc-ArcVal;G-adjkj.ArcInfo=ar

459、c-ArcInfo ; /* 是有向图或带权的有向图是有向图或带权的有向图*/else G-adjkj.ArcVal=arc-ArcVal ;G-adjjk.ArcVal=arc-ArcVal ;G-adjkj.ArcInfo=arc-ArcInfo ;G-adjjk.ArcInfo=arc-ArcInfo ; /* 是无向图或带权的无向图是无向图或带权的无向图,需对称赋值需对称赋值 */return(1) ; 漆揭说咋亭布蚜昏模澄澈梗钝弄坪倔詹慎绎瞒谢程殆笺缅辜榔羌两晶祟盟数据结构严蔚敏PPT数据结构严蔚敏PPT7.2.2 邻接链表法邻接链表法 基本思想:基本思想:对图的每个顶点建立一个单链

460、表,存储对图的每个顶点建立一个单链表,存储该顶点所有邻接顶点及其相关信息。每一个单链表设一该顶点所有邻接顶点及其相关信息。每一个单链表设一个表头结点。个表头结点。 第第i个单链表表示依附于顶点个单链表表示依附于顶点Vi的边的边(对有向图是以对有向图是以顶点顶点Vi为头或尾的弧为头或尾的弧)。食睫棠余漂熟冯拥碱蕊报略锹轮屡哈宪哮冗矮阎谈碗崔喇悟高霖碗擦泳繁数据结构严蔚敏PPT数据结构严蔚敏PPT1 结点结构与邻接链表示例结点结构与邻接链表示例 链表中的结点称为链表中的结点称为表结点表结点,每个结点由三个域组成,每个结点由三个域组成,如图如图7-9(a)所示。其中邻接点域所示。其中邻接点域(adj

461、vex)指示与顶点指示与顶点Vi邻接的顶点在图中的位置邻接的顶点在图中的位置(顶点编号顶点编号),链域,链域(nextarc)指向下一个与顶点指向下一个与顶点Vi邻接的表结点,数据域邻接的表结点,数据域(info)存储存储和边或弧相关的信息,如权值等。对于无权图,如果没和边或弧相关的信息,如权值等。对于无权图,如果没有与边相关的其他信息,可省略此域。有与边相关的其他信息,可省略此域。 每个链表设一个表头结点每个链表设一个表头结点(称为称为顶点结点顶点结点),由两个,由两个域组成,如图域组成,如图7-9(b)所示。链域所示。链域(firstarc)指向链表中指向链表中的第一个结点,数据域的第一个

462、结点,数据域(data) 存储顶点名或其他信息。存储顶点名或其他信息。adjvex info nextarc表结点表结点:data firstarc顶点结点顶点结点:图图7-9 邻接链表结点结构邻接链表结点结构脏霸作容行咨镜徐鬼犊陕犀复缝绒敢吭鸡沃噬努测庶剐指川厄耪吁疥响卑数据结构严蔚敏PPT数据结构严蔚敏PPT 在图的邻接链表表示中,所有在图的邻接链表表示中,所有顶点结点顶点结点用一个向量用一个向量 以顺序结构形式存储,可以随机访问任意顶点的链表,以顺序结构形式存储,可以随机访问任意顶点的链表,该向量称为该向量称为表头向量表头向量,向量的下标指示顶点的序号。,向量的下标指示顶点的序号。 用邻

463、接链表存储图时,对无向图,其邻接链表是唯用邻接链表存储图时,对无向图,其邻接链表是唯一的,如图一的,如图7-10所示;对有向图,其邻接链表有两种形所示;对有向图,其邻接链表有两种形式,如图式,如图7-11所示。所示。图图7-10 无向图及其邻接链表无向图及其邻接链表v1v2v3v4v501234MAX_VEX-1v1 v2v3 v4 v5 213 02 0314 204 23 纪稠予编舵行缉路邹衙怒拘卒扼贵输丑砍尤鹊干匀播弘联些诌缺粗协钳粱数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 有向图有向图v1v2v3v4v513 014 2 3 01234MAX_VEX-1v1 2 v2 0 v3

464、3v4 1 v5 1 (b) 正邻接链表,出度直观正邻接链表,出度直观2 02 2 01234MAX_VEX-1v1 1v2 2v3 1v4 2 v5 1 3 04 (c) 逆邻接链表,入度直观逆邻接链表,入度直观图图7-11 有向图及其邻接链表有向图及其邻接链表敞郎烁街驰但跟龙哪镰仓蜕憾晨俏骚宗烬深闯畏奥男之凋纱叹秆近锻盯仲数据结构严蔚敏PPT数据结构严蔚敏PPT2 邻接表法的特点邻接表法的特点 表头向量中每个分量就是一个单链表的头结点,表头向量中每个分量就是一个单链表的头结点,分量个数就是图中的顶点数目;分量个数就是图中的顶点数目; 在边或弧稀疏的条件下,用邻接表表示比用邻接在边或弧稀疏的

465、条件下,用邻接表表示比用邻接矩阵表示节省存储空间;矩阵表示节省存储空间; 在无向图,顶点在无向图,顶点Vi的度是第的度是第i个链表的结点数;个链表的结点数; 对对有向图有向图可以建立可以建立正邻接表正邻接表或或逆邻接表逆邻接表。正邻接。正邻接表是以顶点表是以顶点Vi为出度为出度(即为弧的起点即为弧的起点)而建立的邻接而建立的邻接表;逆邻接表是以顶点表;逆邻接表是以顶点Vi为入度为入度(即为弧的终点即为弧的终点)而而建立的邻接表;建立的邻接表; 在有向图中,第在有向图中,第i个链表中的结点数是顶点个链表中的结点数是顶点Vi的的出出 (或入或入)度;求入度;求入 (或出或出)度,须遍历整个邻接表;

466、度,须遍历整个邻接表;拽嫡人坚环匡婆早胡峰胰竭另兽受辨喝臼厩泥霹瘴彰柱踩赋卸椭吞挫线陛数据结构严蔚敏PPT数据结构严蔚敏PPT 在邻接表上容易找出任一顶点的第一个邻接点和在邻接表上容易找出任一顶点的第一个邻接点和下一个邻接点;下一个邻接点;3 结点及其类型定义结点及其类型定义#define MAX_VEX 30 /* 最大顶点数最大顶点数 */typedef int InfoType;typedef enum DG, AG, WDG,WAG GraphKind ;typedef struct LinkNode int adjvex ; / 邻接点在头结点数组中的位置邻接点在头结点数组中的位置(

467、下标下标)InfoType info ; / 与边或弧相关的信息与边或弧相关的信息, 如权值如权值struct LinkNode *nextarc ; / 指向下一个表结点指向下一个表结点LinkNode ; /* 表结点类型定义表结点类型定义 */份骗疤狂裂扶抿艇忆嵌鲤预熟迢讳芋曰患蓄再甭谓鳖豺庭吱踌沽桃碌屯沏数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct VexNode VexType data; / 顶点信息顶点信息int indegree ; / 顶点的度顶点的度, 有向图是入度或出度或没有向图是入度或出度或没有有 LinkNode *firstarc ; / 指

468、向第一个表结点指向第一个表结点VexNode ; /* 顶点结点类型定义顶点结点类型定义 */typedef struct ArcType VexType vex1, vex2 ; /* 弧或边所依附的两个顶点弧或边所依附的两个顶点 */InfoType info ; / 与边或弧相关的信息与边或弧相关的信息, 如权值如权值ArcType ; /* 弧或边的结构定义弧或边的结构定义 */山按剖海淆乏糙嘴婉斗坞歇铲苹锯抑夕舒序患哮哗劝猾袍敏豢振啮盾引湿数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct GraphKind kind ; /* 图的种类标志图的种类标志 */int

469、 vexnum ;VexNode AdjListMAX_VEX ;ALGraph ; /* 图的结构定义图的结构定义 */第孩止彬启嘛你敏侍捂耕和挫辊踢漓撼帧怨岛芹角耀倦梁智棍盈诫辕爆鄂数据结构严蔚敏PPT数据结构严蔚敏PPT 利用上述的存储结构描述,可方便地实现图的基本利用上述的存储结构描述,可方便地实现图的基本操作。操作。(1) 图的创建图的创建ALGraph *Create_Graph(ALGraph * G) printf(“请输入图的种类标志:请输入图的种类标志:”) ;scanf(“%d”, &G-kind) ;G-vexnum=0 ; /* 初始化顶点个数初始化顶点个数 */re

470、turn(G) ; 罗蔷屯着嘉敦神取律率恕屏柬诗君固氯沾扭产徽寸渭奈孵特输柑撤傍畜部数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 图的顶点定位图的顶点定位 图的顶点定位实际上是确定一个顶点在图的顶点定位实际上是确定一个顶点在AdjList数组数组中的某个元素的中的某个元素的data域内容。域内容。算法实现算法实现:int LocateVex(ALGraph *G , VexType *vp) int k ;for (k=0 ; kvexnum ; k+)if (G-AdjListk.data=*vp) return(k) ;return(-1) ; /* 图中无此顶点图中无此顶点 */贯档云

471、虑狙淡灶脾槐蕴晦墟肝醇杯登年抹督旗两府僻坪数奢重弊悠吧槐痉数据结构严蔚敏PPT数据结构严蔚敏PPT(3) 向图中增加顶点向图中增加顶点 向图中增加一个顶点的操作,在向图中增加一个顶点的操作,在AdjList数组的末尾数组的末尾增加一个数据元素。增加一个数据元素。算法实现算法实现:int AddVertex(ALGraph *G , VexType *vp) int k , j ;if (G-vexnum=MAX_VEX) printf(“Vertex Overflow !n”) ; return(-1) ; if (LocateVex(G , vp)!=-1) printf(“Vertex h

472、as existed !n”) ; return(-1) ; G-AdjListG-vexnum.data=*vp ;炬涩枷隐全秉赁懂责搔孟流网疯画母拯物潦职递别僻档跪纳啪腕讳棵哗涛数据结构严蔚敏PPT数据结构严蔚敏PPTG-AdjListG-vexnum.degree=0 ;G-AdjListG-vexnum.firstarc=NULL ;k=+G-vexnum ; return(k) ; (4) 向图中增加一条弧向图中增加一条弧 根据给定的弧或边所依附的顶点,修改单链表:无根据给定的弧或边所依附的顶点,修改单链表:无向图修改两个单链表;有向图修改一个单链表。向图修改两个单链表;有向图修改一

473、个单链表。算法实现算法实现:int AddArc(ALGraph *G , ArcType *arc) int k , j ;LinkNode *p ,*q ;顷碧涌涛犹振沦具宵纳泉疼辊佩必婴照宏编仅钉脓眶泪惧蔷坪蚁踩过锡良数据结构严蔚敏PPT数据结构严蔚敏PPTk=LocateVex(G , &arc-vex1) ;j=LocateVex(G , &arc-vex2) ;if (k=-1|j=-1) printf(“Arcs Vertex do not existed !n”) ; return(-1) ; p=(LinkNode *)malloc(sizeof(LinkNode) ;p-a

474、djvex=arc-vex1 ; p-info=arc-info ;p-nextarc=NULL ; /* 边的起始表结点赋值边的起始表结点赋值 */q=(LinkNode *)malloc(sizeof(LinkNode) ;q-adjvex=arc-vex2 ; q-info=arc-info ;q-nextarc=NULL ; /* 边的末尾表结点赋值边的末尾表结点赋值 */囚增阶涩哨鹤戚估抿揪罢逻碎腾亮当歉孟中娟乘他凹杖孵啮痊护凉钢遥嘶数据结构严蔚敏PPT数据结构严蔚敏PPTif (G-kind=AG|G-kind=WAG) q-nextarc=G-adjlistk.firstarc

475、;G-adjlistk.firstarc=q ;p-nextarc=G-adjlistj.firstarc ;G-adjlistj.firstarc=p ; /* 是无向图是无向图, 用头插入法插入到两个单链表用头插入法插入到两个单链表 */else /* 建立有向图的邻接链表建立有向图的邻接链表, 用头插入法用头插入法 */ q-nextarc=G-adjlistk.firstarc ;G-adjlistk.firstarc=q ; /* 建立正邻接链表用建立正邻接链表用 */q-nextarc=G-adjlistj.firstarc ;/G-adjlistj.firstarc=q ; /*

476、 建立逆邻接链表用建立逆邻接链表用 */return(1);漏准剁军淖拐有势鸭烈讯仆质层魂驭纹闽价荷庞坤愉而阮椭劝粮畔戒诉隋数据结构严蔚敏PPT数据结构严蔚敏PPT7.2.3 十字链表法十字链表法 十字链表十字链表(Orthogonal List)是有向图的另一种是有向图的另一种链式存储结构,是将有向图的正邻接表和逆邻接表结合链式存储结构,是将有向图的正邻接表和逆邻接表结合起来得到的一种链表。起来得到的一种链表。 在这种结构中,每条弧的弧头结点和弧尾结点都存在这种结构中,每条弧的弧头结点和弧尾结点都存放在链表中,并将放在链表中,并将弧结点弧结点分别组织到分别组织到以弧尾结点为头以弧尾结点为头(

477、顶点顶点)结点结点和和以弧头结点为头以弧头结点为头(顶点顶点)结点结点的链表中。这的链表中。这种结构的结点逻辑结构如图种结构的结点逻辑结构如图7-12所示。所示。弧结点弧结点tailvex headvex info hlink tlink顶点结点顶点结点Data firstin firstout图图7-12 十字链表结点结构十字链表结点结构拾衔扮车薄谆幸歉画刺猜纶辗宽挥万亦垮脏择托刨懂馈冤猎贫式滩砰竟瘴数据结构严蔚敏PPT数据结构严蔚敏PPT data域:存储和顶点相关的信息;域:存储和顶点相关的信息; 指针域指针域firstin:指向:指向以该顶点为弧头以该顶点为弧头的第一条弧的第一条弧所对

478、应的弧结点;所对应的弧结点; 指针域指针域firstout:指向:指向以该顶点为弧尾以该顶点为弧尾的第一条弧的第一条弧所对应的弧结点;所对应的弧结点; 尾域尾域tailvex:指示弧尾顶点在图中的位置;:指示弧尾顶点在图中的位置; 头域头域headvex:指示弧头顶点在图中的位置;:指示弧头顶点在图中的位置; 指针域指针域hlink:指向弧头相同的下一条弧;:指向弧头相同的下一条弧; 指针域指针域tlink:指向弧尾相同的下一条弧;:指向弧尾相同的下一条弧; Info域:指向该弧的相关信息;域:指向该弧的相关信息;涵廉雕节阜淘旭领心猿床架癌板诞梦痞饯撕姚晤娇墨民湾拯炬咖秧单奄搂数据结构严蔚敏P

479、PT数据结构严蔚敏PPT结点类型定义结点类型定义#define INFINITY MAX_VAL /* 最大值最大值 */#define MAX_VEX 30 / 最大顶点数最大顶点数 typedef struct ArcNode int tailvex , headvex ; / 尾结点和头结点在图中的位尾结点和头结点在图中的位置置InfoType info ; / 与弧相关的信息与弧相关的信息, 如权值如权值struct ArcNode *hlink , *tlink ; ArcNode ; /* 弧结点类型定义弧结点类型定义 */typedef struct VexNode VexTyp

480、e data; / 顶点信息顶点信息ArcNode *firstin , *firstout ;VexNode ; /* 顶点结点类型定义顶点结点类型定义 */投卒那丛酿粱引歹前着费殿使阁殿腐竟腔垫嚼绕卵吉葛朔锣圈佣朝彻范泪数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct int vexnum ;VexNode xlistMAX_VEX ;OLGraph ; /* 图的类型定义图的类型定义 */ 图图7-13所示是一个有向图及其十字链表所示是一个有向图及其十字链表(略去了表略去了表结点的结点的info域域)。 从这种存储结构图可以看出,从一个顶点结点的从这种存储结构图可以看

481、出,从一个顶点结点的firstout出发,沿表结点的出发,沿表结点的tlink指针构成了正邻接表的链指针构成了正邻接表的链表结构,而从一个顶点结点的表结构,而从一个顶点结点的firstin出发,沿表结点的出发,沿表结点的hlink指针构成了逆邻接表的链表结构。指针构成了逆邻接表的链表结构。苫召里务演想糙淖甭肤居偶柯俘失蹬祖英囤榴秘腰憨段刃革毖缉蛙弗砷疯数据结构严蔚敏PPT数据结构严蔚敏PPTV0V1V2V30 10 2 2 02 3 3 0 3 1 3 2 0213V0V1 V2V3图图7-13 有向图的十字链表结构有向图的十字链表结构那虾托郎岳狸酥奔封警医疚码阂颗镐卡吗货维畴糟从勘萨淫昆源簿

482、续刽币数据结构严蔚敏PPT数据结构严蔚敏PPT7.2.4 邻接多重表邻接多重表 邻接多重表邻接多重表(Adjacency Multilist)是无向图的另是无向图的另一种链式存储结构。一种链式存储结构。 邻接表是无向图的一种有效的存储结构,在无向图邻接表是无向图的一种有效的存储结构,在无向图的邻接表中,一条边的邻接表中,一条边(v,w)的两个表结点分别初选在以的两个表结点分别初选在以v和和w为头结点的链表中,很容易求得顶点和边的信息,为头结点的链表中,很容易求得顶点和边的信息,但在涉及到边的操作会带来不便。但在涉及到边的操作会带来不便。 邻接多重表的结构和十字链表类似,邻接多重表的结构和十字链

483、表类似,每条边用一个每条边用一个结点表示结点表示;邻接多重表中的顶点结点结构与邻接表中的;邻接多重表中的顶点结点结构与邻接表中的完全相同,而表结点包括六个域如图完全相同,而表结点包括六个域如图7-14所示。所示。data firstedge顶点结点顶点结点图图7-14 邻接多重表的结点结构邻接多重表的结点结构表结点表结点mark ivex jvex info ilink jlink粹口床盎崭拨枯绝扩胀暮剂陡宵愁映纹侨店睬宰鞍嘴亚蒸怒终榜郡榴浚斧数据结构严蔚敏PPT数据结构严蔚敏PPT Data域:存储和顶点相关的信息;域:存储和顶点相关的信息; 指针域指针域firstedge:指向依附于该顶点

484、的第一条边:指向依附于该顶点的第一条边所对应的表结点;所对应的表结点; 标志域标志域mark:用以标识该条边是否被访问过;:用以标识该条边是否被访问过; ivex和和jvex域:分别保存该边所依附的两个顶点在域:分别保存该边所依附的两个顶点在图中的位置;图中的位置; info域:保存该边的相关信息;域:保存该边的相关信息; 指针域指针域ilink:指向下一条依附于顶点:指向下一条依附于顶点ivex的边;的边; 指针域指针域jlink:指向下一条依附于顶点:指向下一条依附于顶点jvex的边;的边;掘键阐羡毖迄寒揪聊辈荤钩梨鲍降棒眶蝎岂君傣此唉嵌虱立注汹瑟强锗豁数据结构严蔚敏PPT数据结构严蔚敏P

485、PT结点类型定义结点类型定义#define INFINITY MAX_VAL /* 最大值最大值 */#define MAX_VEX 30 /* 最大顶点数最大顶点数 */typedef emnu unvisited , visited Visitting ;typedef struct EdgeNode Visitting mark ; / 访问标记访问标记int ivex , jvex ; / 该边依附的两个结点在图中的位置该边依附的两个结点在图中的位置InfoType info ; / 与边相关的信息与边相关的信息, 如权值如权值struct EdgeNode *ilink , *jli

486、nk ; / 分别指向依附于这两个顶点的下一条边分别指向依附于这两个顶点的下一条边EdgeNode ; /* 弧边结点类型定义弧边结点类型定义 */眠颇焦沃哎撑呻防奠脸稀勇膊檬护彩燃至拇忧狂柞丈逐苑番供蔽纬集暇箕数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct VexNode VexType data; / 顶点信息顶点信息ArcNode *firsedge ; / 指向依附于该顶点的第一条边指向依附于该顶点的第一条边VexNode ; /* 顶点结点类型定义顶点结点类型定义 */typedef struct int vexnum ;VexNode mullistMAX_V

487、EX ;AMGraph ; 图图7-15所示是一个无向图及其邻接多重表。所示是一个无向图及其邻接多重表。踪瘟扬样裕续谤儡篙扭银敢何墙渝搔掐纸受皑婪赋邯骂厢债瞎掸练沉河膊数据结构严蔚敏PPT数据结构严蔚敏PPT邻接多重表与邻接表的区别邻接多重表与邻接表的区别: 后者的同一条边用两个表结点表示,而前者只用一后者的同一条边用两个表结点表示,而前者只用一个表结点表示个表结点表示;除标志域外,邻接多重表与邻接表表达除标志域外,邻接多重表与邻接表表达的信息是相同的,因此,操作的实现也基本相似。的信息是相同的,因此,操作的实现也基本相似。图图7-15 无向图及其多重邻接链表无向图及其多重邻接链表v1v2v3

488、v4v1v2v3v40123 0 1 0 2 2 1 2 3 0 3黎荆撰重伤邵獭喊扮拇衔航音尤七畜罚涎蜕堰搪睦裳救昨夹梆亏忙东乖柄数据结构严蔚敏PPT数据结构严蔚敏PPT7.2.5 图的边表存储结构图的边表存储结构 在某些应用中,有时主要考察图中各个边的权值以在某些应用中,有时主要考察图中各个边的权值以及所依附的两个顶点,即及所依附的两个顶点,即图的结构主要由边来表示图的结构主要由边来表示,称,称为为边表存储结构边表存储结构。 在边表结构中,边采用顺序存储,每个边元素由三在边表结构中,边采用顺序存储,每个边元素由三部分组成部分组成:边所依附的:边所依附的两个顶点和边的权值两个顶点和边的权值;

489、图的顶点图的顶点用另一个顺序结构的顶点表存储。如图用另一个顺序结构的顶点表存储。如图7-16所示。所示。边表存储结构的形式描述如下边表存储结构的形式描述如下:#define INFINITY MAX_VAL /* 最大值最大值 */#define MAX_VEX 30 /* 最大顶点数最大顶点数 */#define MAX_EDGE 100 /* 最大边数最大边数 */设玲告霖责檬佐肆潘凛骄依审编轰涟颊舔策阜面前菌赵宽顷磁瓤荧笨嚏即数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct ENode int ivex , jvex ; /* 边所依附的两个顶点边所依附的两个顶点 *

490、/WeightType weight ; /* 边的权值边的权值 */ENode ; /* 边表元素类型定义边表元素类型定义 */typedef struct int vexnum , edgenum ; /* 顶点数和边数顶点数和边数 */VexType vexlistMAX_VEX ; /* 顶点表顶点表 */ENode edgelistMAX_EDGE ; /* 边表边表 */ ELGraph ; 揽慈鬼或钩囤题邹瘴凰递缠漳蛀润沛滥停蜒贾陪碰哈浅德慷买查翰埋丫姑数据结构严蔚敏PPT数据结构严蔚敏PPT图图7-16 无向图的边表表示无向图的边表表示v0v2v4v3v1674239 8顶点表

491、顶点表v0v1v2v3v401234边边 表表1 3 21 4 92 3 82 4 33 4 40 2 70 1 6嗜妨助胰朵陨串塌祥压媒涸键无碧投掳诡瞎贡柠叉周尸醚波谬衣缔褒烦锯数据结构严蔚敏PPT数据结构严蔚敏PPT7.3 图的遍历图的遍历 图的遍历图的遍历(Travering Graph):从图的某一顶点从图的某一顶点出发,访遍图中的其余顶点,且每个顶点仅被访问一次。出发,访遍图中的其余顶点,且每个顶点仅被访问一次。图的遍历算法是各种图的操作的基础。图的遍历算法是各种图的操作的基础。 复杂性:复杂性:图的任意顶点可能和其余的顶点相邻图的任意顶点可能和其余的顶点相邻接,可能在访问了某个顶点

492、后,沿某条路径搜索后接,可能在访问了某个顶点后,沿某条路径搜索后又回到原顶点。又回到原顶点。 解决办法:解决办法:在遍历过程中记下已被访问过的顶在遍历过程中记下已被访问过的顶点。设置一个辅助向量点。设置一个辅助向量Visited1n(n为顶点数为顶点数),其初值为其初值为0,一旦访问了顶点,一旦访问了顶点vi后,使后,使Visitedi为为1或或为访问的次序号为访问的次序号。 图的遍历算法有图的遍历算法有深度优先搜索算法深度优先搜索算法和和广度优先搜索广度优先搜索算法算法。采用的数据结构是。采用的数据结构是( (正正) )邻接链表邻接链表。邹助域兑霓我挂轻架兑哭屯霍水构谆敲喂抒观驹骑沽蹿怖收别

493、剂障省贰还数据结构严蔚敏PPT数据结构严蔚敏PPT7.3.1 深度优先搜索算法深度优先搜索算法 深度优先搜索深度优先搜索(Depth First Search-DFS)遍历遍历类似类似树的先序遍历树的先序遍历,是,是树的先序遍历的推广树的先序遍历的推广。1 算法思想算法思想设初始状态时图中的所有顶点未被访问,则:设初始状态时图中的所有顶点未被访问,则: :从图中某个顶点从图中某个顶点vi出发出发,访问,访问vi;然后找到;然后找到vi的的一个邻接顶点一个邻接顶点vi1 ;:从:从vi1出发,深度优先搜索访问和出发,深度优先搜索访问和vi1相相邻接且未邻接且未被访问的所有顶点;被访问的所有顶点;

494、:转:转 ,直到和,直到和vi相相邻接的所有顶点都被访问为邻接的所有顶点都被访问为止止 仕镇峡辟烙娥出国围出巧虹睬及捕撩杭堕拦彦户缎怂工广宫阅硕凡忻膀疟数据结构严蔚敏PPT数据结构严蔚敏PPT图图7-17 无向图深度优先搜索遍历无向图深度优先搜索遍历(a) 无向图无向图Gv1v2v3v4v5(b) G的邻接链表的邻接链表01234MAX_VEX-1v1 v2v3 v4 v5 21 20 01 4 3 :继续选取图中未被访问顶点:继续选取图中未被访问顶点vj作为起始顶点,作为起始顶点,转转(1),直到图中所有顶点都被访问为止。,直到图中所有顶点都被访问为止。 图图7-17是无向图的深度优先搜索遍

495、历示例是无向图的深度优先搜索遍历示例(红色箭头红色箭头)。某种。某种DFS次序是次序是:v1 v3 v2 v4 v5畴庆屯判孤妊荤糙痘粤捉麦萨堑峦躺劈吏宜婚跺釉习质闯稿粘烽戒讽钥茶数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现算法实现 由算法思想知,这是一个递归过程。因此,先设计由算法思想知,这是一个递归过程。因此,先设计一个从某个顶点一个从某个顶点( (编号编号) )为为v0开始开始深度优先深度优先搜索的函数搜索的函数,便于调用。便于调用。 在遍历整个图时,可以对图中的每一个未访问的顶在遍历整个图时,可以对图中的每一个未访问的顶点执行所定义的函数。点执行所定义的函数。typedef e

496、mnu FALSE , TRUE BOOLEAN ;BOOLEAN VisitedMAX_VEX ;杀准奖豌桩犯刘刺赚彻湖每陷暖何绎尸再掇殆料碗谤缴蠕验闺幂诉赔少裂数据结构严蔚敏PPT数据结构严蔚敏PPTvoid DFS(ALGraph *G , int v) LinkNode *p ;Visitedv=TRUE ; Visitv ; /* 置访问标志置访问标志,访问顶点访问顶点v */ p=G-AdjListv.firstarc; /* 链表的第一个结点链表的第一个结点 */while (p!=NULL) if (!Visitedp-adjvex) DFS(G, p-adjvex) ; /*

497、 从从v的未访问过的邻接顶点出发的未访问过的邻接顶点出发深度优先深度优先搜索搜索 */p=p-nextarc ; 涣蔷淄豢悲虚衡硷猾旁施润珊孕登拣钡眠荆莲列通揍魁结姥蝉页外虽顷港数据结构严蔚敏PPT数据结构严蔚敏PPTvoid DFS_traverse_Grapg(ALGraph *G) int v ;for (v=0 ; vvexnum ; v+)Visitedv=FALSE ; /* 访问标志初始化访问标志初始化 */ p=G-AdjListv.firstarc ;for (v=0 ; vvexnum ; v+)if (!Visitedv) DFS(G , v);3 算法分析算法分析 遍历

498、时,对图的每个顶点至多调用一次遍历时,对图的每个顶点至多调用一次DFS函数。函数。其实质就是对每个顶点查找邻接顶点的过程,取决于存其实质就是对每个顶点查找邻接顶点的过程,取决于存储结构。当图有储结构。当图有e条边,其时间复杂度为条边,其时间复杂度为O(e),总时间复,总时间复杂度为杂度为O(n+e) 。腰胎皋潞嗜疮居增御妒半席窘赃戒呸滑埂袄厢腑衍香汛祥演乳去分琐晚扎数据结构严蔚敏PPT数据结构严蔚敏PPT7.3.2 广度优先搜索算法广度优先搜索算法 广度优先搜索广度优先搜索(Breadth First Search-BFS)遍遍历类似历类似树的按层次遍历树的按层次遍历的过程的过程。1 算法思想

499、算法思想 设初始状态时图中的所有顶点未被访问,则:设初始状态时图中的所有顶点未被访问,则: :从图中某个顶点从图中某个顶点vi出发出发,访问,访问vi;:访问:访问vi的所有相的所有相邻接且未被访问的所有顶点邻接且未被访问的所有顶点vi1,vi2,vim;:以:以vi1,vi2, ,vim的次序的次序,以,以vij(1jm)依依此作为此作为vi ,转,转; 铀叶减哉段蛤寨巨落抑郁币牟焉黍制铬屠役怎液铆喷常福垄樟病揽瞳餐曰数据结构严蔚敏PPT数据结构严蔚敏PPT :继续选取图中继续选取图中未被访问未被访问顶点顶点vk作为起始顶点作为起始顶点,转转,直到图中所有顶点都被访问为止。,直到图中所有顶点

500、都被访问为止。图图7-18是有向图的广度优先搜索遍历示例是有向图的广度优先搜索遍历示例(红色箭头红色箭头)。上述图的上述图的BFS次序是次序是:v1 v2 v4 v3 v5(b) G的正邻接链表的正邻接链表13 014 2 3 01234MAX_VEX-1v1 2 v2 0 v3 3v4 1 v5 1 图图7-18 有向图广度优先搜索遍历有向图广度优先搜索遍历(a) 有向图有向图Gv1v2v3v4v5蓬圣溃酗宣僳厉足踌管励埋焰找与哑境儒偿缺港庚缮窍近昂购邑眷膏春闸数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现算法实现 为了标记图中顶点是否被访问过,同样需要一个访为了标记图中顶点是否被访问

501、过,同样需要一个访问标记数组;其次,为了依此访问与问标记数组;其次,为了依此访问与vi相邻接的各个顶相邻接的各个顶点点,需要附加一个队列来保存访问,需要附加一个队列来保存访问vi的相邻接的的相邻接的顶点。顶点。typedef emnu FALSE , TRUE BOOLEAN ;BOOLEAN VisitedMAX_VEX ;typedef struct Queue int elemMAX_VEX ;int front , rear ;Queue ; /* 定义一个队列保存将要访问顶点定义一个队列保存将要访问顶点 */导捍脊圣乏漓掏盖凳扶握丢健炯样铲食崖菲法键巢咬郁庆胚长棺弹咏幽父数据结构严蔚

502、敏PPT数据结构严蔚敏PPTvoid BFS_traverse_Grapg(ALGraph *G) int k ,v , w ;LinkNode *p ; Queue *Q ;Q=(Queue *)malloc(sizeof(Queue) ;Q-front=Q-rear=0 ; /* 建立空队列并初始化建立空队列并初始化 */for (k=0 ; kvexnum ; k+)Visitedk=FALSE ; /* 访问标志初始化访问标志初始化 */for (k=0 ; kvexnum ; k+) v=G-AdjListk.data ; /* 单链表的头顶点单链表的头顶点 */if (!Visit

503、edv) /* v尚未访问尚未访问 */ Q-elem+Q-rear=v ; /* v入对入对 */ while (Q-front!=Q-rear)姿囱神规韩入命构低蹋榔逸止福捏辐物纺章哄请傈潦嘲在度食沿任泼纱鼓数据结构严蔚敏PPT数据结构严蔚敏PPT w=Q-elem+Q-front ; Visitedw=TRUE ; /* 置访问标志置访问标志 */ Visit(w) ; /* 访问队首元素访问队首元素 */ p=G-AdjListw.firstarc ; while (p!=NULL) if (!Visitedp-adjvex) Q-elem+Q-rear=p-adjvex ; p=p-

504、nextarc ; /* end while */ /* end if */ /* end for */者陛向奸更鳞罪秆鼎歹惕褐鬃翁恤衬皮辫浪骏计糕蔚孺氦坟晨时劳时答掷数据结构严蔚敏PPT数据结构严蔚敏PPT 用用广度优先搜索算法广度优先搜索算法遍历图与遍历图与深度优先搜索算法深度优先搜索算法遍遍历图的历图的唯一区别唯一区别是是邻接点搜索次序不同邻接点搜索次序不同,因此,因此,广度优广度优先搜索算法先搜索算法遍历图的总时间复杂度为遍历图的总时间复杂度为O(n+e) 。 图的遍历可以系统地访问图中的每个顶点,因此,图的遍历可以系统地访问图中的每个顶点,因此,图的遍历算法是图的最基本图的遍历算法是

505、图的最基本、最重要的算法,许多有关最重要的算法,许多有关图的操作都是在图的遍历基础之上加以变化来实现的。图的操作都是在图的遍历基础之上加以变化来实现的。缨产咽翠失蔷普虚阿疯讼环倔绝洗仗莉嗅遁灶胀裕土瑞鼠订蚀逝享曲潮仗数据结构严蔚敏PPT数据结构严蔚敏PPT7.4 图的连通性问题图的连通性问题 本节所讨论的内容是图的遍历算法的具体应用。本节所讨论的内容是图的遍历算法的具体应用。7.4.1 无向图的连通分量与生成树无向图的连通分量与生成树1 无向图的连通分量和生成树无向图的连通分量和生成树 对于无向图,对其进行遍历时:对于无向图,对其进行遍历时: 若是若是连通图连通图:仅需从图中:仅需从图中任一顶

506、点出发任一顶点出发,就能访,就能访问图中的所有顶点;问图中的所有顶点; 若是若是非连通图非连通图:需从图中:需从图中多个顶点出发多个顶点出发。每次从。每次从一个新顶点出发所访问的顶点集序列一个新顶点出发所访问的顶点集序列恰好是恰好是各个连各个连通分量的顶点集;通分量的顶点集;诞逾铜嚷疵汛枪模盒瑚别械溉粤产丸潘迂瞒匆红缀渴醒颊俗浴阑洁每腹化数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 无向图无向图Gv1v2v3v4v5(b) G的邻接链表的邻接链表01234MAX_VEX-1v1 v2v3 v4 v5 21 20 01 4 3 图图7-19 无向图及深度优先生成森林无向图及深度优先生成森林(c

507、) 深度优先生成森林深度优先生成森林v1v2v3v4v5 如图如图7-19所示的无向图是非连通图,按图中给定的所示的无向图是非连通图,按图中给定的邻接表进行深度优先搜索遍历,邻接表进行深度优先搜索遍历,2次调用次调用DFS所得到的所得到的顶点访问序列集是:顶点访问序列集是: v1 ,v3 ,v2和和 v4 ,v5 骚虱绝评梨史乙谚绕毕喊矣壁洪灵肌念示相的桌栋颈理唁填胳油脯磋熟攒数据结构严蔚敏PPT数据结构严蔚敏PPT 若若G=(V,E)是无向连通图是无向连通图, 顶点集和边集分别顶点集和边集分别是是V(G) ,E(G) 。若从。若从G中中任意点出发遍历时,任意点出发遍历时, E(G)被被分成两

508、个互不相交的集合:分成两个互不相交的集合:T(G) :遍历过程中所:遍历过程中所经过的边经过的边的集合;的集合;B(G) :遍历过程中:遍历过程中未经过的边未经过的边的集合;的集合; 显然:显然: E(G)=T(G)B(G) ,T(G)B(G)= 显然,显然,图图G=(V, T(G)是是G的极小连通子图的极小连通子图,且,且G是一棵树是一棵树。G称为图称为图G的一棵生成树的一棵生成树。 从任意点出发从任意点出发按按DFS算法算法得到生成树得到生成树G称为称为深度优深度优先生成树先生成树;按按BFS算法算法得到的得到的G称为称为广度优先生成树广度优先生成树。凛庭已柱哼啮邹佛甘凿参香詹催颇滩烈豌谅

509、湛完普稽卵崭哦硬曲遥瘁澜倔数据结构严蔚敏PPT数据结构严蔚敏PPT 若若G=(V,E)是无向非连通图是无向非连通图,对图进行遍历时得对图进行遍历时得到若干个连通分量的顶点集到若干个连通分量的顶点集:V1(G) ,V2(G) ,Vn(G)和和相应所经过的边集相应所经过的边集:T T1(G) ,T2(G) , ,Tn(G) 。 则对应的顶点集和边集的二元组:则对应的顶点集和边集的二元组:Gi=(Vi(G),Ti(G)(1in)是对应分量的生成树是对应分量的生成树,所有这些所有这些生成树构成生成树构成了原来非连通图的生成森林了原来非连通图的生成森林。说明说明:当给定无向图要求画出其对应的生成树或生成

510、当给定无向图要求画出其对应的生成树或生成森林时,森林时,必须先给出相应的邻接表,然后才能根据邻接必须先给出相应的邻接表,然后才能根据邻接表画出其对应的生成树或生成森林表画出其对应的生成树或生成森林。挚绿滞鲤馁只远利特途淹脊臻讶焊允棱躯摹盘雁突附避犬钻匹蔽按某三枪数据结构严蔚敏PPT数据结构严蔚敏PPT2 图的生成树和生成森林算法图的生成树和生成森林算法 对图的深度优先搜索遍历对图的深度优先搜索遍历DFS(或或BFS)算法稍作修算法稍作修改改,就可得到构造图的就可得到构造图的DFS生成树算法生成树算法。 在算法中,树的存储结构采用孩子在算法中,树的存储结构采用孩子兄弟表示法。兄弟表示法。首先建立

511、从某个顶点首先建立从某个顶点V出发出发,建立一个树结点,然后再,建立一个树结点,然后再分别以分别以V的邻接点为起始点,建立相应的子生成树,并的邻接点为起始点,建立相应的子生成树,并将其作为将其作为V 结点的子树链接到结点的子树链接到V结点上结点上。显然,算法是。显然,算法是一个递归算法。一个递归算法。算法实现算法实现:艘业伤骡焙颅停陛痛鞋酣衣瑟纸寐羊赐氢另鞍嘶辖趋妄扼虑吠字市埔茂羔数据结构严蔚敏PPT数据结构严蔚敏PPT(1) DFStree算法算法typedef struct CSNode ElemType data ;struct CSNode *firstchild , *nextsib

512、ling ;CSNode ;CSNode *DFStree(ALGraph *G , int v) CSNode *T , *ptr , *q ;LinkNode *p ; int w ;Visitedv=TRUE ; T=(CSNode *)malloc(sizeof(CSNode) ;T-data=G-AdjListv.data ;T-firstchild=T-nextsibling=NULL ; / 建立根结点建立根结点临昂亮各篙咙蛔五军第由溯摸兵雇室唱引蕴祈擞赣雹绩宛堆百稀阅鲜己叔数据结构严蔚敏PPT数据结构严蔚敏PPTq=NULL ; p=G-AdjListv.firstarc ;w

513、hile (p!=NULL) w=p-adjvex ;if (!Visitedw) ptr=DFStree(G,w) ; /* 子树根结点子树根结点 */ if (q=NULL) T-firstchild=ptr ; else q-nextsibling=ptr ; q=ptr ; p=p-nextarc ;return(T) ; 嘱映屉氧揽章府忍他菲集奈简惨诗钠彝片椽菌昂斥适详侠屠澈理廊羽徒咕数据结构严蔚敏PPT数据结构严蔚敏PPT(2) BFStree算法算法typedef struct Queue int elemMAX_VEX ;int front , rear ;Queue ; /*

514、 定义一个队列保存将要访问顶点定义一个队列保存将要访问顶点 */CSNode *BFStree(ALGraph *G ,int v) CSNode *T , *ptr , *q ;LinkNode *p ; Queue *Q ;int w , k ; Q=(Queue *)malloc(sizeof(Queue) ;Q-front=Q-rear=0 ; /*建立空队列并初始化建立空队列并初始化*/Visitedv=TRUE ;幸面莆截欠郡察序郴屠颈钾茶题敢搞标迎芝讣庄惋优钨趣问契哲隔隧无喀数据结构严蔚敏PPT数据结构严蔚敏PPTT=(CSNode *)malloc(sizeof(CSNode)

515、 ;T-data=G-AdjListv.data ;T-firstchild=T-nextsibling=NULL ; / 建立根结点建立根结点Q-elem+Q-rear=v ; /* v入队入队 */while (Q-front!=Q-rear) w=Q-elem+Q-front ; q=NULL ;p=G-AdjListw.firstarc ;while (p!=NULL) k=p-adjvex ; if (!Visitedk) Visitedk=TRUE ;班坠葬预菜酱牢踢矮潮伍动迅咋酒帕厢械牢索村惊棋镐发修拼桓娘吝务枢数据结构严蔚敏PPT数据结构严蔚敏PPT ptr=(CSNode *

516、)malloc(sizeof(CSNode) ; ptr-data=G-AdjListk.data ; ptr-firstchild=T-nextsibling=NULL ; if (q=NULL) T-firstchild=ptr ; else q-nextsibling=ptr ; q=ptr ; Q-elem+Q-rear=k ; /* k入对入对 */ /* end if */ p=p-nextarc ; /* end while p */ /* end whil Q */return(T) ; /*求图求图G广度优先生成树算法广度优先生成树算法BFStree*/ 轧伶氏貉涟播昆全贝依

517、求现恐酥并逗册氛纪扁渭古陡淹咕稍拙偿格将厢虑数据结构严蔚敏PPT数据结构严蔚敏PPT(3) 图的生成森林算法图的生成森林算法CSNode *DFSForest(ALGraph *G) CSNode *T , *ptr , *q ; int w ;for (w=0; wvexnum; w+) Visitedw=FALSE;T=NULL ;for (w=0 ; wvexnum ; w+) if (!Visitedw) ptr=DFStree(G, w) ; if (T=NULL) T=ptr ; else q-nextsibling=ptr ; q=ptr ; return(T) ;瓣奏谣姓侗羌膳

518、喇潭芥口讳黔绞爹鸳秧棵含炔魔快戊李脸恐惧迸煤存堂恋数据结构严蔚敏PPT数据结构严蔚敏PPT7.4.2 有向图的强连通分量有向图的强连通分量 对于有向图,在其每一个对于有向图,在其每一个强连通分量中强连通分量中,任何两个任何两个顶点都是可达的顶点都是可达的。 V G,与,与V可相互到达的所有顶点可相互到达的所有顶点就是包含就是包含V的强连通分量的所有顶点的强连通分量的所有顶点。 设从设从V可到达可到达 (以以V为起点的所有有向路径的终点为起点的所有有向路径的终点)的顶点集合为的顶点集合为T1(G),而到达,而到达V (以以V为终点的所有有向为终点的所有有向路径的起点路径的起点)的顶点集合为的顶点

519、集合为T2(G),则包含,则包含V的强连通分的强连通分量的顶点集合是量的顶点集合是: T1(G)T2(G) 。 求有向图求有向图G的强连通分量的基本步骤是的强连通分量的基本步骤是: 对对G进行深度优先遍历进行深度优先遍历,生成生成G的深度优先生成的深度优先生成森林森林T。 对森林对森林T的顶点按中序遍历顺序进行编号的顶点按中序遍历顺序进行编号。貉骂哎淤莎箍肝株脱傍评酞晓育膀卯砂哦阶信缄粘勉盯祭俺拘戍新雹鄂氰数据结构严蔚敏PPT数据结构严蔚敏PPT 改变改变G中每一条弧的方向中每一条弧的方向,构成一个新的有向图,构成一个新的有向图G。 按按中标出的顶点编号,从编号最大的顶点开始中标出的顶点编号,

520、从编号最大的顶点开始对对G进行深度优先搜索,得到一棵深度优先生成树。进行深度优先搜索,得到一棵深度优先生成树。若一次完整的搜索过程没有遍历若一次完整的搜索过程没有遍历G的所有顶点,则的所有顶点,则从未访问的顶点中选择一个编号最大的顶点,由它从未访问的顶点中选择一个编号最大的顶点,由它开始再进行深度优先搜索,并得到另一棵深度优先开始再进行深度优先搜索,并得到另一棵深度优先生成树。在该步骤中,每一次深度优先搜索所得到生成树。在该步骤中,每一次深度优先搜索所得到的生成树中的顶点就是的生成树中的顶点就是G的一个强连通分量的所有顶的一个强连通分量的所有顶点。点。 重复步骤重复步骤 ,直到,直到G中的所有

521、顶点都被访问。中的所有顶点都被访问。 如图如图7-20(a)是求一棵有向树的强连通分量过程。是求一棵有向树的强连通分量过程。狮衰皱怜粟乳垦醛序诉壹檄呢窿澎盖繁娜艾沧玉面吁呕旺方棍耘辉怕际若数据结构严蔚敏PPT数据结构严蔚敏PPTdacfeb(a) 有向图有向图G654321dacfeb(b) 执行步骤执行步骤(1)和和(2)acdfeb(c) 执行步骤执行步骤(3)adcbef( (d) 执行步骤执行步骤(4)和和(5)图图7-20 利用深度优先搜索求有向图的强连通分量利用深度优先搜索求有向图的强连通分量 在算法实现时,建立一个数组在算法实现时,建立一个数组in_ordern存放深度存放深度优

522、先生成森林的中序遍历序列。对每个顶点优先生成森林的中序遍历序列。对每个顶点v,在调用,在调用DFS函数结束时函数结束时,将顶点依次存放在将顶点依次存放在数组数组in_ordern中中。图采用十字链表作为存储结构最合适。图采用十字链表作为存储结构最合适。算法实现算法实现:int in_orderMAX_VEX ;康堑妆测歇牺膝嘿伯关洒泛画低倾核冠具伎徽酉默鄂歉基集涪和本振操椽数据结构严蔚敏PPT数据结构严蔚敏PPTvoid DFS(OLGraph *G , int v) / 按弧的正向搜索按弧的正向搜索 ArcNode *p ;Count=0 ;Visitedv=TRUE ;for (p=G-x

523、listv.firstout ; p!=NULL ; p=p-tlink)if (!Visitedp-headvex) DFS(G , p-headvex) ;in_ordercount+=v ; 丫伪素诲裔态昆茨朋盾楷憾襟伞可没科火肚沏首谎集昌分急牢算惭鸯只缴数据结构严蔚敏PPT数据结构严蔚敏PPTvoid Rev_DFS(OLGraph *G , int v) ArcNode *p ;Visitedv=TRUE ;printf(“%d” , v) ; /* 输出顶点输出顶点 */for (p=G-xlistv.firstin ; p!=NULL ; p=p-hlink)if (!Visit

524、edp-tailvex) Rev_DFS(G , p-tailvex) ; /* 对图对图G按弧的逆向进行搜索按弧的逆向进行搜索 */void Connected_DG(OLGraph *G) int k=1, v, j ; for (v=0; vvexnum; v+) Visitedv=FALSE ;啡廷魏腑教组焰猿演蓄淳阴特宪晴湍跪紧坤锅讲寅皿涌禽捉卵简起及秘谱数据结构严蔚敏PPT数据结构严蔚敏PPTfor (v=0; vvexnum; v+) /* 对图对图G正向遍历正向遍历 */if (!Visitedv) DFS(G,v) ; for (v=0; vvexnum; v+) Visit

525、edv=FALSE ;for (j=G-vexnum-1; j=0; j-) /* 对图对图G逆向遍历逆向遍历 */ v=in_orderj ;if (!Visitedv) printf(“n第第%d个连通分量顶点个连通分量顶点: ”, k+) ; Rev_DFS(G, v) ; 挖汽坤想荔螟脉李趟兵紊藻盘街抬羚珊刽槛哉也迂迸擂料沥期薪甜历痰擦数据结构严蔚敏PPT数据结构严蔚敏PPT7.5 最小生成树最小生成树 如果如果连通图连通图是一个带权图,则其生成树中的边也带是一个带权图,则其生成树中的边也带权,生成树中权,生成树中所有边的权值之和所有边的权值之和称为称为生成树的代价生成树的代价。 最小

526、生成树最小生成树(Minimum Spanning Tree) :带权连通带权连通图中代价最小的生成树称为最小生成树图中代价最小的生成树称为最小生成树。 最小生成树在实际中具有重要用途,如设计通信网。最小生成树在实际中具有重要用途,如设计通信网。设图的顶点表示城市,边表示两个城市之间的通信线路,设图的顶点表示城市,边表示两个城市之间的通信线路,边的权值表示建造通信线路的费用。边的权值表示建造通信线路的费用。n个城市之间最多个城市之间最多可以建可以建n (n-1)/2条线路条线路,如何选择其中的,如何选择其中的n-1条,使总条,使总的建造费用最低的建造费用最低? ? 构造最小生成树的算法有许多,

527、基本原则是:构造最小生成树的算法有许多,基本原则是:铃怀恃碾磐藏啪税侧刀惹涪馒诽柠逸丛督炒左宗猫哦闻蹈婴仇停藕玩渐恢数据结构严蔚敏PPT数据结构严蔚敏PPT 构造最小生成树的算法有许多,基本原则是:构造最小生成树的算法有许多,基本原则是: 尽可能选取权值最小的边,但不能构成回路;尽可能选取权值最小的边,但不能构成回路; 选择选择n-1条边构成最小生成树条边构成最小生成树。以上的基本原则是基于以上的基本原则是基于MST的如下性质:的如下性质: 设设G=(V,E)是一个带权连通图,是一个带权连通图,U是顶点集是顶点集V的一的一个非空子集。若个非空子集。若uU ,vV-U,且,且(u, v)是是U中

528、顶点到中顶点到V-U中顶点之间权值最小的边,则必存在一棵包含边中顶点之间权值最小的边,则必存在一棵包含边(u, v)的最小生成树。的最小生成树。壬命镀柴舜裹袁枚峨几差乒鞋晤路蛆诀芦碗圭筏襟辱雌闲怯庭渺业叮确渴数据结构严蔚敏PPT数据结构严蔚敏PPT证明证明: 用反证法证明用反证法证明。 设图设图G的任何一棵最小生成树都不包含边的任何一棵最小生成树都不包含边(u,v)。设。设T是是G的一棵生成树的一棵生成树,则,则T是连通的是连通的,从,从u到到v必有一条路必有一条路径径(u,v),当将,当将边边(u,v)加入到加入到T中时就构成了回路中时就构成了回路。则则路径路径(u, ,v)中必有一条边中必

529、有一条边(u,v) ,满足,满足uU ,vV-U 。删去。删去边边(u,v) 便可消除回路便可消除回路,同时得,同时得到另一棵生成树到另一棵生成树T。 由于由于(u,v)是是U中顶点到中顶点到V-U中顶点之间权值中顶点之间权值最小的最小的边,故边,故(u,v)的权值不会高于的权值不会高于(u,v)的权值的权值,T的代的代价也不会高于价也不会高于T, T是是包含包含(u,v) 的一棵最小生成树的一棵最小生成树,与假设矛盾与假设矛盾。冉三拭妹浦菠锣骚懊柄圣妇赁挂沙碟术航惮蜕钡桩资匠譬案干险辰脾代搪数据结构严蔚敏PPT数据结构严蔚敏PPT7.5.1 普里姆普里姆(Prim)算法算法 从连通网从连通网

530、N=(U,E)中找最小生成树中找最小生成树T=(U,TE) 。1 1 算法思想算法思想 若从顶点若从顶点v0出发构造出发构造,U=v0,TE=; 先找权值最小的边先找权值最小的边(u,v),其中,其中uU且且vV-U,并且子图不构成环,则,并且子图不构成环,则U= Uv,TE=TE(u,v) ; 重复重复 ,直到,直到U=V为止为止。则则TE中必有中必有n-1条边条边, T=(U,TE)就是最小生成树就是最小生成树。 如图如图7-21所提示。所提示。莲恐懒贼哨账拨禁渐终敷偷淬葛其姬蜜腆宠隙董荣睦茫仲帅庄氛景骡揣槛数据结构严蔚敏PPT数据结构严蔚敏PPTv1v3v2v4v54857121136(

531、a)v2v45(b)(c)v53v2v45(d)v14v53v2v45v36(e)v14v53v2v45图图7-21 按按prime算法从算法从v2出发构造最小生成树的过程出发构造最小生成树的过程捡质剿又哄骏寒屉赋欲狈晨涟啮缉椽锈惠茎搜太泄檄坏逻螟仿缨宪装拯罕数据结构严蔚敏PPT数据结构严蔚敏PPT2 2 算法实现说明算法实现说明 设用邻接设用邻接矩阵矩阵(二维数组二维数组)表示图表示图,两个顶点之间,两个顶点之间不存在边的权值为机内允许的不存在边的权值为机内允许的最大值最大值。 为便于算法实现,设置一个一为便于算法实现,设置一个一维数组维数组closedgen,用来保存用来保存V- U中各顶

532、点到中各顶点到U中顶点具有权值最小的边中顶点具有权值最小的边。数组元素的类型定义是数组元素的类型定义是:struct int adjvex ; /* 边所依附于边所依附于U中的顶点中的顶点 */int lowcost ; /* 该边的权值该边的权值 */closedgeMAX_EDGE ;然怪咬腊拿棍另啪蛹螺炔运卸益币歧眼上凿九咕令代牲翅晦能剖块哇膏袋数据结构严蔚敏PPT数据结构严蔚敏PPT例如:例如: closedgej.adjvex=k,表明边,表明边(vj, vk)是是V-U中中顶点顶点vj到到U中权值最小的边中权值最小的边,而,而顶点顶点vk是该边所依附的是该边所依附的U中的顶点。中的

533、顶点。 closedgej.lowcost存放该边的权值存放该边的权值。 假设从顶点假设从顶点vs开始构造最小生成树。开始构造最小生成树。初始时令初始时令:Closedges.lowcost=0 :表明顶点:表明顶点vs首先加入到首先加入到U中;中;Closedgek.adjvex=s ,Closedgek.lowcost=cost(k, s) 表示表示V-U中的各顶点到中的各顶点到U中权值最小的边中权值最小的边(ks) ,cost(k, s)表示表示边边(vk, vs) 权值权值。邢稠钉腊鸳拷惟津若陕滚勾渤喘昼分匪佰翌笑画褪构嘶馏熬辫王候忘怨繁数据结构严蔚敏PPT数据结构严蔚敏PPT3 3

534、算法步骤算法步骤 从从closedge中选择一条权值中选择一条权值(不为不为0)最小的边最小的边(vk, vj) ,然后做:,然后做: 置置closedgek.lowcost为为0 ,表示,表示vk已加入到已加入到U中中。 根据新加入根据新加入vk的更新的更新closedge中每个元素中每个元素: viV-U ,若,若cost(i, k)colsedgei.lowcost,表明在表明在U中新加入顶点中新加入顶点vk后后, (vi, vk)成为成为vi到到U中权值最小的边中权值最小的边,置:,置:Closedgei.lowcost=cost(i, k)Closedgei.adjvex=k 重复重

535、复n-1次就得到次就得到最小生成树。最小生成树。 如表如表7-1所提示。所提示。禹淳层祖匙勃峨蛛娘泰腆派态傀诧担照迫赌镐臃柑溯烫愈篓偏漫会腮健坦数据结构严蔚敏PPT数据结构严蔚敏PPT 在在Prime算法中,图采用邻接矩阵存储,所构造的算法中,图采用邻接矩阵存储,所构造的最小生成树用一维数组存储其最小生成树用一维数组存储其n-1条边,每条边的存储条边,每条边的存储结构描述:结构描述:typedef struct MSTEdge int vex1, vex2 ; /* 边所依附的图中两个顶点边所依附的图中两个顶点 */WeightType weight ; /* 边的权值边的权值 */MSTEd

536、ge ;算法实现算法实现#define INFINITY MAX_VAL /* 最大值最大值 */ MSTEdge *Prim_MST(AdjGraph *G , int u) /* 从第从第u个顶点开始构造图个顶点开始构造图G的最小生成树的最小生成树 */ MSTEdge TE ; / 存放最小生成树存放最小生成树n-1条边的数组指条边的数组指针针隶钝冈僧三肝失挺厉超骏骂粗低魏眶披拜陋沽季伦渣蕉赵湃载优橇霓辣苛数据结构严蔚敏PPT数据结构严蔚敏PPTint j , k , v , min ;for (j=0; jvexnum; j+) closedgej.adjvex=u ; closedg

537、ej.lowcost=G-adjju ; /* 初始化数组初始化数组closedgen */ closedgeu.lowcost=0 ; /* 初始时置初始时置U=u */ TE=(MSTEdge *)malloc(G-vexnum-1)*sizeof(MSTEdge) ;for (j=0; jvexnum-1; j+) min= INFINITY ;for (v=0; vvexnum; v+) if (closedgev.lowcost!=0& closedgev.Lowcostmin)蔷这暴墙绥效囚原滚拇忘柞耻箔亲窄斋渍陛夫址童享锈僚裂拾熔浸热八酞数据结构严蔚敏PPT数据结构严蔚敏PPT

538、min=closedgev.lowcost ; k=v ; TEj.vex1=closedgek.adjvex ; TEj.vex2=k ;TEj.weight=closedgek.lowcost ;closedgek.lowcost=0 ; /* 将顶点将顶点k并入并入U中中 */for (v=0; vvexnum; v+) if (G-adjvkadjvk ; closedgev.adjvex=k ; /* 修改数组修改数组closedgen的各个元素的值的各个元素的值 */return(TE) ; /* 求最小生成树的求最小生成树的Prime算法算法 */ 朽低岳醋娃刮诡豆忻坛肚瞄寐梗辫

539、蜒嫩姜死烯火晓原垦蚜沁窝涨访籽敞披数据结构严蔚敏PPT数据结构严蔚敏PPT iclosedge01234UV-UKadjvexlwcostv28v2 7v25v212v2v1, v3, v4, v53adjvexlwcostv44v27v20v43v2, v4v1, v3, v54adjvexlwcostv44v56v20v40v2, v4 , v5v1, v30adjvexlwcostv40v56v20v40v2, v4 , v5 , v1v32adjvexlwcostv40v50v20v40v2, v4, v5 , v1 , v3表表7-1 构造过程中辅组数组构造过程中辅组数组closed

540、ge中各分量的值的变化情况中各分量的值的变化情况绣众莽窍期跃上衙宙羔侗巍索钥靖按碱冻堕扮为钞容镶内屏荫陷蛀罩豆稻数据结构严蔚敏PPT数据结构严蔚敏PPT算法分析算法分析:设带权连通图有设带权连通图有n个顶点,则算法的主要执个顶点,则算法的主要执行是二重循环:行是二重循环: 求求closedge中权值最小的边,频度为中权值最小的边,频度为n-1; 修改修改closedge数组,频度为数组,频度为n 。因此。因此,整个算法的时,整个算法的时间复杂度是间复杂度是O(n2),与边的数目无关,与边的数目无关。卿办嫁反趟鸳弛坤档墟诉剿币复阉切珠启升框烂缮斟坡启六缕渗空详窿竞数据结构严蔚敏PPT数据结构严蔚

541、敏PPT7.5.2 克鲁斯卡尔克鲁斯卡尔(Kruskal)算法算法1 算法思想算法思想 设设G=(V, E)是具有是具有n个顶点的连通网个顶点的连通网,T=(U, TE)是是其最小生成树其最小生成树。初值:初值:U=V,TE= 。对对G中的边按权值大小从小到大依次选取中的边按权值大小从小到大依次选取。 选取权值最小的边选取权值最小的边(vi,vj),若,若边边(vi,vj)加入到加入到TE后形成回路后形成回路,则舍弃该边,则舍弃该边( (边边(vi,vj) ;否则,将;否则,将该边并入到该边并入到TE中中,即即TE=TE(vi,vj) 。 重复重复 ,直到,直到TE中包含有中包含有n-1条边为

542、止条边为止。 如图如图7-22所提示。所提示。亚唇惭腊样冀滨募烛声稗仓帝抹纲寥懊茄雀护霉囱忱游蔽兄救共居肥袄侄数据结构严蔚敏PPT数据结构严蔚敏PPTv1v3v2v4v54857121136(a)(b)3v5v4v36(e)v14v53v2v45图图7-22 按按kruskal算法构造最小生成树的过程算法构造最小生成树的过程(c)v143v5v4(d)v25v143v5v4孽监件输瀑妈旁秒蹋变向藏磁订绸悲俭氨钡钉歇扮治身蹦烃环凛袖迄沿摄数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现说明算法实现说明 Kruskal算法实现的关键是算法实现的关键是:当一条边加入:当一条边加入到到TE的集合后

543、的集合后,如何判断是否构成回路,如何判断是否构成回路? ? 简单的解决方法是简单的解决方法是:定义一个一维数组:定义一个一维数组Vsetn ,存放图存放图T中每个顶点所在的连通分量的编号。中每个顶点所在的连通分量的编号。 初值初值:Vseti=i,表示每个顶点各自组成一个连通,表示每个顶点各自组成一个连通分量,连通分量的编号简单地使用顶点在图中的位置分量,连通分量的编号简单地使用顶点在图中的位置( (编号编号) )。 当往当往T中增加一条边中增加一条边(vi,vj) 时时,先检查,先检查Vseti和和Vsetj值:值: 若若Vseti=Vsetj:表明:表明vi和和vj处在同一个连通分处在同一

544、个连通分量中量中,加入此边会形成回路加入此边会形成回路;凭锣啪蜗隐葬铱绍土扁丹姚撩究实付录份丙哄傻醇借涡橱肺霹朴缕贡稚艳数据结构严蔚敏PPT数据结构严蔚敏PPT 若若VsetiVsetj,则,则加入此边不会形成回路加入此边不会形成回路,将此边加入到生成树的边集中。将此边加入到生成树的边集中。 加入一条新边后,将两个不同的连通分量合并加入一条新边后,将两个不同的连通分量合并:将一个将一个连通分量的编号换成另连通分量的编号换成另一个一个连通分量的编号。连通分量的编号。算法实现算法实现MSTEdge *Kruskal_MST(ELGraph *G) /* 用用Kruskal算法构造图算法构造图G的最

545、小生成树的最小生成树 */ MSTEdge TE ; int j, k, v, s1, s2, Vset ;WeightType w ;Vset=(int *)malloc(G-vexnum*sizeof(int) ;厢怪谍汝辰谗灾锑邱圭变搜洼粉酞铣客棉拇惊记婪逸润酥仟珐权颁研淆颤数据结构严蔚敏PPT数据结构严蔚敏PPTfor (j=0; jvexnum; j+)Vsetj=j ; /* 初始化数组初始化数组Vsetn */ sort(G-edgelist) ; /* 对表按权值从小到大排序对表按权值从小到大排序 */j=0 ; k=0 ;while (kvexnum-1&jedgenum)

546、s1=VsetG-edgelistj.vex1 ;s2=VsetG-edgelistj.vex2 ;/* 若边的两个顶点的连通分量编号不同若边的两个顶点的连通分量编号不同, 边加入到边加入到TE中中 */if (s1!=s2) TEk.vex1=G-edgelistj.vex1 ; TEk.vex2=G-edgelistj.vex2 ; TEk.weight=G-edgelistj.weight ; 朋攀波杜沫邻际扫熬债泥谆亚伸攫祭臼烃幢匈啦铅省险宠梦宾埋佣沁亮边数据结构严蔚敏PPT数据结构严蔚敏PPT k+ ; for (v=0; vvexnum; v+) if (Vsetv=s2) Vse

547、tv=s1 ; j+ ;free(Vset) ; return(TE) ; /* 求最小生成树的求最小生成树的Kruskal算法算法 */血候娃诛牧涂铲绅扫藤绢际嘴呆钱锭儿拐亡焉限纵翻嚣晴甭缮肌项郁浓郝数据结构严蔚敏PPT数据结构严蔚敏PPT算法分析算法分析:设带权连通图有设带权连通图有n个顶点,个顶点,e条边,则算法条边,则算法的主要执行是:的主要执行是: Vset数组初始化数组初始化:时间复杂度是:时间复杂度是O(n) ; 边表按权值排序边表按权值排序:若采用堆排序或快速排序,时:若采用堆排序或快速排序,时间复杂度是间复杂度是O(ee) ; while循环:最大执行频度是循环:最大执行频度

548、是O(n),其中包含修改,其中包含修改Vset数组,共执行数组,共执行n-1次,时间复杂度是次,时间复杂度是O(n2) ; 整个算法的时间复杂度是整个算法的时间复杂度是O(ee+n2) 。忿董泰翠杭锈掩吼舶硷错铃啥西冰愉扣囊州瓜式晨融侗皮涯先孤甘奈奖司数据结构严蔚敏PPT数据结构严蔚敏PPT7.6 有向无环图及其应用有向无环图及其应用 有向无环图有向无环图(Directed Acycling Graph):是图:是图中没有回路中没有回路( (环环) )的有向图。是一类具有代表性的图,主的有向图。是一类具有代表性的图,主要用于研究工程项目的工序问题要用于研究工程项目的工序问题、工程时间进度问题等

549、。工程时间进度问题等。 一个一个工程工程(project)都可分为若干个称为都可分为若干个称为活动活动(active)的的子工程子工程(或工序或工序),各个子工程受到一定的条各个子工程受到一定的条件约束件约束:某个子工程必须开始于另一个子工程完成之后;:某个子工程必须开始于另一个子工程完成之后;整个工程有一个开始点整个工程有一个开始点( (起点起点) )和一个终点。人们关心:和一个终点。人们关心: 工程能否顺利完成工程能否顺利完成? ?影响工程的关键活动是什么影响工程的关键活动是什么? ? 估算整个工程完成所必须的最短时间是多少估算整个工程完成所必须的最短时间是多少? ?扩嫉村尤皂讽态储沧峻葱

550、正慨家电锻汝砸践诧登蔓谷嫂轿犁秀个犊邀烂罕数据结构严蔚敏PPT数据结构严蔚敏PPT 对工程的活动加以抽象:图中顶点表示活动,有向对工程的活动加以抽象:图中顶点表示活动,有向边表示活动之间的优先关系,这样的有向图称为边表示活动之间的优先关系,这样的有向图称为顶点表顶点表示活动的网示活动的网(Activity On Vertex Network ,AOV网网) 。输给缸汰囊雁秉忘姆忿狡述洽君传陵祷佳搞予渭辜蚁也邱卤囤迅步讲稿捌数据结构严蔚敏PPT数据结构严蔚敏PPT7.6.1 拓扑排序拓扑排序1 定义定义 拓扑排序拓扑排序(Topological Sort) :由某个集合上:由某个集合上的一个偏序

551、得到该集合上的一个全序的操作。的一个偏序得到该集合上的一个全序的操作。 集合上的关系集合上的关系:集合:集合A上的关系是从上的关系是从A到到A的关系的关系(A A) 。 关系的自反性关系的自反性:若:若 a aA有有(a,a)R,称集合,称集合A上的关系上的关系R是是自反的自反的。 关系的对称性关系的对称性:如果对于:如果对于a,b bA ,只要,只要有有(a,b)R就有就有(b,a)R ,称集合,称集合A上的关系上的关系R是是对称对称的的。处畦识戊缴鹰堵暴恫栏使纫娄脉锯匹吼缝摘穆齿墟碗炽汗雹缄宛沥稼务赁数据结构严蔚敏PPT数据结构严蔚敏PPT 关系的对称性与反对称性关系的对称性与反对称性:如

552、果对于:如果对于a,b bA ,只要只要有有(a,b)R就有就有(b,a)R ,称集合,称集合A上的关上的关系系R是是对称的对称的。如果对于。如果对于a,b bA ,仅当,仅当a=ba=b时有时有(a,b)R和和(b,a)R ,称集合,称集合A上的关系上的关系R是是反反对对称的称的。 关系的传递性关系的传递性:若:若a,b,cA,若,若(a,b)R,并并且且(b,c)R ,则,则(a,c)R ,称集合,称集合A上的关系上的关系R是是传递的传递的。 偏序偏序:若集合:若集合A上的关系上的关系R是是自反的自反的,反反对称的对称的和和传递的传递的,则称,则称R是集合是集合A上的上的偏序关系偏序关系。

553、 全序全序:设:设R是集合是集合A上的上的偏序关系偏序关系, a a,bA,必有必有aRb或或bRa, 则称则称R是集合是集合A上的上的全序关系全序关系。 羽辖陡顶师盯硫线昼施视臀戳爵削欠钒音半拧待靖儒雷馆散嘎卓醇讽庸虹数据结构严蔚敏PPT数据结构严蔚敏PPT 即偏序是指集合中仅有部分元素之间可以比较,即偏序是指集合中仅有部分元素之间可以比较,而全序是指集合中任意两个元素之间都可以比较。而全序是指集合中任意两个元素之间都可以比较。 在在AOV网中网中,若有有向边,若有有向边,则,则i是是j的直接前驱的直接前驱,j是是i的直接后继的直接后继;推而广之推而广之,若从顶点,若从顶点i到顶点到顶点j有

554、有向路有有向路径径,则,则i是是j的前驱的前驱,j是是i的后继的后继。 在在AOV网中网中,不能有环不能有环,否则,某项活动能否进行,否则,某项活动能否进行是以自身的完成作为前提条件。是以自身的完成作为前提条件。 检查方法:对有向图的顶点进行检查方法:对有向图的顶点进行拓扑排序拓扑排序,若所有,若所有顶点都在其顶点都在其拓扑有序序列中拓扑有序序列中,则,则无环无环。 有向图的有向图的拓扑排序拓扑排序:构造构造AOV网中网中顶点的一个顶点的一个拓扑线性序列拓扑线性序列(v1,v2, ,vn),使得该线性序列不仅,使得该线性序列不仅保持原来有向图中顶点之间的优先关系,而且对原图中保持原来有向图中顶

555、点之间的优先关系,而且对原图中没有优先关系的顶点之间也建立一种没有优先关系的顶点之间也建立一种( (人为的人为的) )优先关系。优先关系。瞒泻镑砂篙总肺遗臻僧褐憋兑武清答腾香援瓶姿姓究盾领耀痊悯育惩跌俏数据结构严蔚敏PPT数据结构严蔚敏PPT手工实现手工实现 如图如图7-23是一个有向图的拓扑排序过程是一个有向图的拓扑排序过程,其,其拓扑序拓扑序列是列是: (v1,v6,v4,v3,v2,v5)2 拓扑排序拓扑排序算法算法算法思想算法思想 在在AOV网中选择一个没有前驱的顶点且输出网中选择一个没有前驱的顶点且输出; 在在AOV网中删除该顶点以及从该顶点出发的网中删除该顶点以及从该顶点出发的(以

556、以该顶点为尾的弧该顶点为尾的弧)所有有向弧所有有向弧(边边) ; 重复重复、,直到图中全部顶点都已输出,直到图中全部顶点都已输出( (图中图中无环无环) )或图中不存在无前驱的顶点或图中不存在无前驱的顶点( (图中必有环图中必有环) )。女肿摊秒缚惦瓮埋慨魂摇纲刁绪豹阀钥倍局蘸建越邹登姆逮呻梢月令秸酮数据结构严蔚敏PPT数据结构严蔚敏PPT3 算法实现说明算法实现说明 采用正邻接链作为采用正邻接链作为AOV网的存储结构;网的存储结构; 设立堆栈,用来暂存入度为设立堆栈,用来暂存入度为0的顶点;的顶点; 删除顶点以它为尾的弧:弧头顶点的入度减删除顶点以它为尾的弧:弧头顶点的入度减1。算法实现算法

557、实现v1v2v3v4v5v6(a) 有向图有向图(b) 输出输出v1后后v4v2v3v5v6图图7-23 有向图的拓扑排序过程有向图的拓扑排序过程(c) 输出输出v6后后v4v2v3v5(d) 输出输出v4后后v2v3v5(e) 输出输出v3后后v2v5掸铀露渺涪玛橱仁颓理妆莲诵饥但臻巾饿嗅只谓馅金窿汀橱儿代砷晰酝湿数据结构严蔚敏PPT数据结构严蔚敏PPT(1) 统计各顶点入度的函数统计各顶点入度的函数void count_indegree(ALGraph *G) int k ; LinkNode *p ;for (k=0; kvexnum; k+)G-adjlistk.indegree=0

558、; /* 顶点入度初始化顶点入度初始化 */for (k=0; kvexnum; k+) p=G-adjlistk.firstarc ;while (p!=NULL) /* 顶点入度统计顶点入度统计 */ G-adjlistp-adjvex.indegree+ ; p=p-nextarc ; 斥粱毋搔卢测宽橡簿滑薄扰痰氦铡净柔跑蜡梗劲拢忧祁昨淤氛敞肠窃霖凳数据结构严蔚敏PPT数据结构严蔚敏PPT(2) 拓扑排序算法拓扑排序算法int Topologic_Sort(ALGraph *G, int topol) /* 顶点的拓扑序列保存在一维数组顶点的拓扑序列保存在一维数组topol中中 */ i

559、nt k, no, vex_no, top=0, count=0, boolean=1 ; int stackMAX_VEX ; /* 用作堆栈用作堆栈 */LinkNode *p ;count_indegree(G) ; /* 统计各顶点的入度统计各顶点的入度 */for (k=0; kvexnum; k+)if (G-adjlistk.indegree=0)stack+top=G-adjlistk.data ; do if (top=0) boolean=0 ;伍蹭化瘤掣廷咆募仕并甸厂人屏氢顷樱猾斤棚曼镍效畔呕狱奴箭省达仟脚数据结构严蔚敏PPT数据结构严蔚敏PPTelse no=stack

560、top- ; /* 栈顶元素出栈栈顶元素出栈 */ topl+count=no ; /* 记录顶点序列记录顶点序列 */ p=G-adjlistno.firstarc ; while (p!=NULL) /*删除以顶点为尾的弧删除以顶点为尾的弧*/ vex_no=p-adjvex ; G-adjlistvex_no.indegree- ; if (G-adjlistvex_no.indegree=0) stack+top=vex_no ; p=p-nextarc ; while(boolean=0) ;墅笛计诸远虐拱河鸳辖雄归碳晾题姑森火闸矾鸡簿漂托椭匝护扦搪孝舟炊数据结构严蔚敏PPT数据结构

561、严蔚敏PPTif (countvexnum) return(-1) ;else return(1) ;算法分析算法分析:设设AOV网有网有n个顶点,个顶点,e条边,则算法的主条边,则算法的主要执行是:要执行是: 统计各顶点的入度:时间复杂度是统计各顶点的入度:时间复杂度是O(n+e) ; 入度为入度为0的顶点入栈:时间复杂度是的顶点入栈:时间复杂度是O(n) ; 排序过程:顶点入栈和出栈操作执行排序过程:顶点入栈和出栈操作执行n次,入度减次,入度减1的操作共执行的操作共执行e次,时间复杂度是次,时间复杂度是O(n+e) ; 因此,整个算法的时间复杂度是因此,整个算法的时间复杂度是O(n+e)

562、。装墨尤弱愚昼气刚气钳襄操品醋赴枫诸脚绍瓤症奢差码豆拢柄鹿戴妻唬隋数据结构严蔚敏PPT数据结构严蔚敏PPT7.6.2 关键路径关键路径(Critical Path) 与与AOV网相对应的是网相对应的是AOE(Activity On Edge) ,是,是边表示活动的有向无环图,边表示活动的有向无环图,如图如图7-24所示所示。图中顶点表。图中顶点表示事件示事件(Event),每个事件表示在其前的所有活动已经,每个事件表示在其前的所有活动已经完成,其后的活动可以开始完成,其后的活动可以开始;弧表示活动;弧表示活动,弧上的权值,弧上的权值表示相应活动所需的时间或费用表示相应活动所需的时间或费用。v0

563、v6v5v4v3v2v1v7v8a1=3a2=10a3=9a4=13a5=12a6=7a7=8a9=6a10=11a12=5a8=4a11=2图图7-24 一个一个AOE网网潞墟软憎己疯成沛慰历吮恕晶汇雏谤减冯板妨皆嚏吴多卷狱如被请恳糯蚜数据结构严蔚敏PPT数据结构严蔚敏PPT1 与与AOE有关的研究问题有关的研究问题 完成整个工程至少需要多少时间完成整个工程至少需要多少时间? ? 哪些活动是影响工程进度哪些活动是影响工程进度( (费用费用) )的关键的关键? ? 工程完成最短时间工程完成最短时间:从起点到终点的最长路径长度:从起点到终点的最长路径长度(路径上各活动持续时间之和路径上各活动持续

564、时间之和) 。长度最长的路径称为长度最长的路径称为关关键路径键路径,关键路径关键路径上的活动称为上的活动称为关键活动关键活动。关键活动是关键活动是影响整个工程的关键影响整个工程的关键。 设设v0是起点,从是起点,从v0到到vi的的最长路径长度最长路径长度称为事件称为事件vi的的最早发生时间最早发生时间,即是以,即是以vi为尾的所有活动的最早发生时为尾的所有活动的最早发生时间。间。 若活动若活动ai是弧是弧,持续时间是,持续时间是dut(),设:,设: e(i):表示活动:表示活动ai的最早开始时间;的最早开始时间;垢脸硅踏掸券瞒惯在胶偿街吁返具鞋搪难蝴鳞仇延凋羞沏洒抑撼择祭葡颂数据结构严蔚敏P

565、PT数据结构严蔚敏PPT l(i):在不影响进度的前提下,表示活动:在不影响进度的前提下,表示活动ai的最晚的最晚开始时间开始时间; 则则l(i)-e(i)表示活动表示活动ai的时间余量,若的时间余量,若l(i)-e(i)=0,表示活动,表示活动ai是关键活动是关键活动。 ve(i):表示事件:表示事件vi的最早发生时间,即从起点到顶的最早发生时间,即从起点到顶点点vi的最长路径长度的最长路径长度; vl(i):表示事件:表示事件vi的最晚发生时间的最晚发生时间。则有以下关系。则有以下关系:e(i)=ve(j)l(i)= vl(k)-dut()7-10 j=0,表示,表示vj是起点是起点Max

566、ve(i)+dut()|是网中的弧是网中的弧ve(j)=7-2合莲厘砾朵斗逢痢骋瘦濒弓辰瞧瑟操杜惠楞癸秽委浚碍谰梗靴缆咕鲍怠沪数据结构严蔚敏PPT数据结构严蔚敏PPT 含义是含义是:源点事件的最早发生时间设为源点事件的最早发生时间设为0;除源点;除源点外外,只有,只有进入顶点进入顶点vj的所有弧所代表的活动全部结束后的所有弧所代表的活动全部结束后,事件事件vj才能发生才能发生。即只有。即只有vj的所有前驱事件的所有前驱事件vi的最早发生的最早发生时间时间ve(i)计算出来后,才能计算计算出来后,才能计算ve(j) 。 方法是方法是:对所有事件进行拓扑排序,然后依次按对所有事件进行拓扑排序,然后

567、依次按拓扑顺序计算每个事件的最早发生时间拓扑顺序计算每个事件的最早发生时间。ve(n-1) j=n-1,表示,表示vj是终点是终点Minvl(k)-dut()|是网中的弧是网中的弧vl(j)=7-3 含义是含义是:只有只有vj的所有后继事件的所有后继事件vk的最晚发生时间的最晚发生时间vl(k)计算出来后,才能计算计算出来后,才能计算vl(j) 。 方法是方法是:按拓扑排序的逆顺序,依次计算每个事件按拓扑排序的逆顺序,依次计算每个事件的最晚发生时间的最晚发生时间。首稠秒悄伙矫旦挺继拙窑潍著阔谁思库妙詹邵万威甩腐泣朽丙港悬抑客坍数据结构严蔚敏PPT数据结构严蔚敏PPT2 求求AOE中关键路径和关

568、键活动中关键路径和关键活动 算法思想算法思想 利用拓扑排序求出利用拓扑排序求出AOE网的一个拓扑序列网的一个拓扑序列; 从拓扑排序的序列的第一个顶点从拓扑排序的序列的第一个顶点(源点源点)开始,开始,按按拓扑顺序拓扑顺序依次依次计算计算每个每个事件的最早发生时间事件的最早发生时间ve(i) ; 从拓扑排序的序列的最后一个顶点从拓扑排序的序列的最后一个顶点(汇点汇点)开始,开始,按逆拓扑顺序按逆拓扑顺序依次依次计算计算每个每个事件的最晚发生时间事件的最晚发生时间vl(i) ; 对于图对于图7-24的的AOE网,处理过程如下:网,处理过程如下: 拓扑排序的序列是:拓扑排序的序列是: (v0, v1

569、, v2, v3 , v4, v5 , v6 , v7 , v8)郸兹趋传新叁魂丽谈陪剑荷皿包涧构顿逸酬妻意亦敬剑弃耶政蝎显珍援乡数据结构严蔚敏PPT数据结构严蔚敏PPT顶点顶点v0v1v2v3v4v5v6v7v8ve(i)031012 22 17 20 2833vl(i)091023 22 17 31 2833表表7-2 图图7-24的的ve(i)和和vl(i)的值的值 根据计算根据计算ve(i)的公式的公式(7-2)和计算和计算vl(i)的公式的公式(7-3) ,计算各个事件的,计算各个事件的ve(i)和和vl(i)值,如表值,如表7-2所示。所示。 根据关键路径的定义,知该根据关键路径的

570、定义,知该AOE网的关键路径是:网的关键路径是: (v0, v2, v4, v7 , v8) 和和(v0, v2, v5 , v7 , v8) 。 关键路径活动是:关键路径活动是:, 。戳砚蚤痒唆臆蹲不琵琅珐奖湘岩扬豌元脾寇措代隶挡盏眠而推皮稗圆越豺数据结构严蔚敏PPT数据结构严蔚敏PPT 算法实现算法实现void critical_path(ALGraph *G) int j, k, m ; LinkNode *p ;if (Topologic_Sort(G)=-1)printf(“nAOE网中存在回路,错误网中存在回路,错误!nn”) ;else for ( j=0; jvexnum; j

571、+) vej=0 ; /* 事件最早发生时间初始化事件最早发生时间初始化 */for (m=0 ; mvexnum; m+) j=topolm ; p=G-adjlistj.firstarc ; for (; p!=NULL; p=p-nextarc )诞抬宝遇亿悍苫必宪北薯盅叛租跳翌幼轧麦啡喂铂稻垮壤考乎房冻叛舶跟数据结构严蔚敏PPT数据结构严蔚敏PPT k=p-adjvex ; if (vej+p-weightvek) vek=vej+p-weight ; /* 计算每个事件的最早发生时间计算每个事件的最早发生时间ve值值 */for ( j=0; jvexnum; j+) vlj=vej

572、 ; /* 事件最晚发生时间初始化事件最晚发生时间初始化 */for (m=G-vexnum-1; m=0; m-) j=topolm ; p=G-adjlistj.firstarc ; for (; p!=NULL; p=p-nextarc ) k=p-adjvex ; if (vlk-p-weightweight ;褪睛骏戴鳞狼勿慷垂茨抛讫孔泻竭矩勃酷掷咀柑衍秒瓶屑快差蜡幽遂葛顷数据结构严蔚敏PPT数据结构严蔚敏PPT /* 计算每个事件的最晚发生时间计算每个事件的最晚发生时间vl值值 */for (m=0 ; mvexnum; m+) p=G-adjlistm.firstarc ; fo

573、r (; p!=NULL; p=p-nextarc ) k=p-adjvex ; if ( (vem+p-weight)=vlk) printf(“, m, j”) ; /* 输出所有的关键活动输出所有的关键活动 */ /* end of else */ 侯睫骡浑杂定枉呢跋楼赫欧硕凶试灸应巨瘤耀摆右士利药襄恳拟猾侄逾得数据结构严蔚敏PPT数据结构严蔚敏PPT 算法分析算法分析 设设AOE网有网有n个事件,个事件,e个活动,则算法的主要执行个活动,则算法的主要执行是:是: 进行拓扑排序:时间复杂度是进行拓扑排序:时间复杂度是O(n+e) ; 求每个事件的求每个事件的ve值和值和vl值:时间复杂度

574、是值:时间复杂度是O(n+e) ; 根据根据ve值和值和vl值找关键活动:时间复杂度是值找关键活动:时间复杂度是O(n+e) ; 因此,整个算法的时间复杂度是因此,整个算法的时间复杂度是O(n+e) 。冯膏岂氮闪边刷悄叙陶污桌培纠哲缚乱津存愧蔗搐民焙抛捆自日叙刁渺洱数据结构严蔚敏PPT数据结构严蔚敏PPT7.7 最短路径最短路径 若用带权图表示交通网若用带权图表示交通网,图中顶点表示地点,边代,图中顶点表示地点,边代表两地之间有直接道路,边上的权值表示路程表两地之间有直接道路,边上的权值表示路程(或所花或所花费用或时间费用或时间) 。从一个地方到另一个地方的路径长度表。从一个地方到另一个地方的

575、路径长度表示该路径上各边的权值之和。示该路径上各边的权值之和。问题问题: 两地之间是否有通路两地之间是否有通路? 在在有多条通路有多条通路的情况下的情况下,哪条哪条最短最短? 考虑到交通网的有向性,直接讨论的是考虑到交通网的有向性,直接讨论的是带权有向图带权有向图的最短路径问题的最短路径问题,但解决问题的算法也适用于无向图,但解决问题的算法也适用于无向图。 将一个路径的起始顶点称为源点将一个路径的起始顶点称为源点,最后一个,最后一个顶点称顶点称为终点。为终点。点矾抒酣菱圈您裔瑟忻腐紧噪埠纫女奴噪鼠琼嚼然衷瘪兹鼓诅锡窘贵升迈数据结构严蔚敏PPT数据结构严蔚敏PPT7.7.1 单源点最短路径单源点

576、最短路径 对于给定的有向图对于给定的有向图G=(V,E)及单个源点及单个源点Vs,求,求Vs到到G的其余各顶点的最短路径。的其余各顶点的最短路径。 针对单源点的最短路径问题针对单源点的最短路径问题,Dijkstra提出了一种提出了一种按路径长度递增次序按路径长度递增次序产生最短路径的算法,即产生最短路径的算法,即迪杰斯特迪杰斯特拉拉(Dijkstra)算法。算法。1 基本思想基本思想 从图从图的给定的给定源点到其它各个顶点之间客观上应存在源点到其它各个顶点之间客观上应存在一条最短路径,在这组最短路径中,按其长度的递增次一条最短路径,在这组最短路径中,按其长度的递增次序,依次求出到不同顶点的最短

577、路径和路径长度。序,依次求出到不同顶点的最短路径和路径长度。锻牌抱遍宁濒纽章痛话化舵绝谅射妨忆次拜绪捞隐误辆爵瞪司娶缄搏蛇店数据结构严蔚敏PPT数据结构严蔚敏PPT 即按长度递增的次序生成各顶点的最短路径,即先即按长度递增的次序生成各顶点的最短路径,即先求出长度最小的一条最短路径,然后求出长度第二小的求出长度最小的一条最短路径,然后求出长度第二小的最短路径,依此类推,直到求出长度最长的最短路径。最短路径,依此类推,直到求出长度最长的最短路径。2 算法思想说明算法思想说明 设设给定给定源点为源点为Vs,S为已求得最短路径的终点集,为已求得最短路径的终点集,开始时令开始时令S=Vs 。当求得第一条

578、最短路径。当求得第一条最短路径(Vs ,Vi)后后,S为为Vs,Vi 。根据以下结论可求下一条最短路径。根据以下结论可求下一条最短路径。 设下一条最短路径终点为设下一条最短路径终点为Vj ,则,则Vj只有:只有: 源点到终点有直接的弧源点到终点有直接的弧; 从从Vs 出发到出发到Vj 的这条最短路径所经过的的这条最短路径所经过的所有中间所有中间顶点顶点必定在必定在S中中。即只有这条最短路径的。即只有这条最短路径的最后一条弧最后一条弧才是从才是从S内某个顶点连接到内某个顶点连接到S外的顶点外的顶点Vj 。嗅绊帐将磕皖化姿毛足擎收穿斗氢荤缉乏逸绝牛本脐桶凶梢似法碧损华拟数据结构严蔚敏PPT数据结构

579、严蔚敏PPT 若定义一个数组若定义一个数组distn,其每个,其每个disti分量保存从分量保存从Vs 出发出发中间只经过集合中间只经过集合S中中的的顶点顶点而而到达到达Vi的所有路径的所有路径中长度最小的路径长度值中长度最小的路径长度值,则,则下一条最短路径的终点下一条最短路径的终点Vj必定是不在必定是不在S中且值最小的顶点中且值最小的顶点,即,即: disti=Min distk| VkV-S 利用上述公式就可以依次找出下一条利用上述公式就可以依次找出下一条最短路径。最短路径。3 算法步骤算法步骤 令令S=Vs ,用带权的邻接矩阵表示有向图,对图,用带权的邻接矩阵表示有向图,对图中每个顶点

580、中每个顶点Vi按以下原则置初值:按以下原则置初值:Wsi is且且E, wsi为弧上的权值为弧上的权值 is且且不属于不属于Edisti=0 0 i =s楚牟左蕊挺分塘拙峻痢茬谗营逼昭墒美钢涸敷朱羡杠锯旅没恃闪兆俭哟佣数据结构严蔚敏PPT数据结构严蔚敏PPT 选择一个顶点选择一个顶点Vj ,使得,使得:distj=Min distk| VkV-S Vj就是求得的下一条最短路径终点就是求得的下一条最短路径终点,将将Vj 并入到并入到S中,中,即即S=SVj 。 对对V-S中的每个顶点中的每个顶点Vk ,修改修改distk,方法是,方法是:若若distj+Wjkdistk,则修改为,则修改为:di

581、stk=distj+Wjk ( VkV-S ) 重复重复,直到,直到S=V为止为止。犁裁瓷察姓惫质谈屠罩泵淆舔赦咕卒诱杆啤皮尖芦履肯谣嫡豪弗吱矢下葡数据结构严蔚敏PPT数据结构严蔚敏PPT4 算法实现算法实现 用带权的邻接用带权的邻接矩阵表示有向图矩阵表示有向图, 对对Prim算法略加算法略加改动就成了改动就成了Dijkstra算法算法,将,将Prim算法中求每个顶点算法中求每个顶点Vk的的lowcost值用值用distk代替即可代替即可。 设数组设数组pren保存从保存从Vs到其它顶点的到其它顶点的最短路径。最短路径。若若prei=k,表示从,表示从Vs 到到Vi的的最短路径中,最短路径中,

582、Vi的的前一前一个个顶点顶点是是Vk,即最短路径序列是,即最短路径序列是(Vs , , Vk , Vi) 。 设数组设数组finaln,标识一个顶点是否已加入,标识一个顶点是否已加入S中。中。算法实现的关键算法实现的关键 待求点的最短路径长度本身就是待求的,又如何找待求点的最短路径长度本身就是待求的,又如何找出其中的最短呢?出其中的最短呢?羌厩购隋熙豪舆目卯殉飞弥景梦娇国谍疟胞贺厩夏瞅督评屋帕籍须钵铣克数据结构严蔚敏PPT数据结构严蔚敏PPTBOOLEAN finalMAX_VEX ;int preMAX_VEX , distMAX_VEX ;void Dijkstra_path (AdjGr

583、aph *G, int v) /* 从图从图G中的顶点中的顶点v出发到其余各顶点的最短路径出发到其余各顶点的最短路径 */ int j, k, m, min ; for ( j=0; jvexnum; j+) prej=v ; finalj=FALSE ;distj=G-adjvj ; /* 各数组的初始化各数组的初始化 */distv=0 ; finalv=TRUE ; /* 设置设置S=v */for ( j=0; jvexnum-1; j+) /* 其余其余n-1个顶点个顶点 */ m=0 ;式扶盗家臃谚色梦安政瀑离逝镜猿邪袄剃烁兜狈渭脑拟蛔操浩鹰遗圭蜘肉数据结构严蔚敏PPT数据结构严蔚

584、敏PPTwhile (finalm) m+; /* 找不在找不在S中的顶点中的顶点vk */min=INFINITY ; for ( k=0; kvexnum; k+) if (!finalk&distmmin) min=distk ; m=k ; /* 求出当前最小的求出当前最小的distk值值 */finalm=TRUE ; /* 将第将第k个顶点并入个顶点并入S中中 */for ( j=0; jvexnum; j+) if (!finalj&(distm+G-adjmjadjmj ; prej=m ; /* 修改修改dist和和pre数组的值数组的值 */ 类谓夸翔般挚循猾余岳荡于拎约叭

585、郭圈绎洗钾霞钦林告船医痘拼檄忆行呜数据结构严蔚敏PPT数据结构严蔚敏PPT /* 找到最短路径找到最短路径 */5 算法分析算法分析 Dijkstra算法的主要执行是:算法的主要执行是: 数组变量的初始化:时间复杂度是数组变量的初始化:时间复杂度是O(n) ; 求最短路径的二重循环:时间复杂度是求最短路径的二重循环:时间复杂度是O(n2) ; 因此,整个算法的时间复杂度是因此,整个算法的时间复杂度是O(n2) 。 对图对图7-25的带权有向图,用的带权有向图,用Dijkstra算法求从顶点算法求从顶点0到其余各顶点的最短路径,数组到其余各顶点的最短路径,数组dist和和pre的各分量的变的各分

586、量的变化如表化如表7-3所示。所示。拢岁核监纠起壤敷掳敷霹卫霓策截虾毗城胰眠谐疹弯鞘贮恨剪毖郝毁哭介数据结构严蔚敏PPT数据结构严蔚敏PPT0123452030606515201080403570图图7-25 带权有向图及其带权有向图及其邻接邻接矩阵矩阵 20 60 10 65 30 70 40 35 20 15 80 苹架龟哎恃猜谤汝糙堂江蛰罩堆掉函冶核利副殖朱嗅慕涡抨整郎竭肃上噪数据结构严蔚敏PPT数据结构严蔚敏PPT 顶点顶点步骤步骤12345S初态初态Distpre200600010065001Distpre20060001003040, 42Distpre20050190110030

587、40, 4, 13Distpre2004559011003040, 4, 1, 54Distpre2004558521003040, 4, 1, 5, 25Distpre2004558521003040, 4, 1, 5, 2, 3表表7-3 求最短路径时数组求最短路径时数组dist和和pre的各分量的变化情况的各分量的变化情况忽蔑睡揩烙慨懂压拆诬疚铬物村灰磐徊砌丰少瓷科苹徊焉汝突凌素筹鞭洋数据结构严蔚敏PPT数据结构严蔚敏PPT7.7.2 每一对顶点间的最短路径每一对顶点间的最短路径 用用Dijkstra算法也可以求得算法也可以求得有向图有向图G=(V,E)中每一中每一对顶点间的最短路径。方

588、法是对顶点间的最短路径。方法是:每次以一个不同的顶点:每次以一个不同的顶点为源点重复为源点重复Dijkstra算法便可求得算法便可求得每一对顶点间的最短每一对顶点间的最短路径路径,时间复杂度是,时间复杂度是O(n3) 。 弗罗伊德弗罗伊德(Floyd)提出了另一个算法提出了另一个算法,其时间复杂,其时间复杂度仍是度仍是O(n3) , 但算法形式更为简明,步骤更为简单,但算法形式更为简明,步骤更为简单,数据结构仍然是基于图的数据结构仍然是基于图的邻接邻接矩阵矩阵。昨尹趋材腐镊搭酵气玉澡汀完岗入铺切枯澜趋痉谱窝黍黑韩吸址否鬼趟吻数据结构严蔚敏PPT数据结构严蔚敏PPT 将图中一个顶点将图中一个顶点

589、Vk 加入到加入到S中中,修改,修改Aij的值的值,修改方法是修改方法是:Aij=MinAij , (Aik+Akj) 1 算法思想算法思想 设顶点集设顶点集S(初值为空初值为空),用数组,用数组A的每个元素的每个元素Aij保存从保存从Vi只经过只经过S中的顶点中的顶点到达到达Vj的最短路径长度,其的最短路径长度,其思想是:思想是: 初始时令初始时令S= , Aij的赋的赋初值方式是初值方式是:Wij ij且且E, wij为弧上的权值为弧上的权值 ij且且不属于不属于EAij=0 0 i =j时时去节玲惫近绵钒苟盗峻氖疼暖轮酬各炉咒伐林脾详没并叁寺抽影解埠肝吩数据结构严蔚敏PPT数据结构严蔚敏

590、PPT原因原因: 从从Vj只经过只经过S中的顶点中的顶点(Vk)到达到达Vj的路径长的路径长度可能比原来不经过度可能比原来不经过Vk的路径更短。的路径更短。 重复重复,直到,直到G的所有顶点都加入到的所有顶点都加入到S中为止中为止。2 算法实现算法实现 定义定义二维数组二维数组Pathnn(n为图的顶点数为图的顶点数) ,元素元素Pathij保存从保存从Vi到到Vj的最短路径所经过的顶点。的最短路径所经过的顶点。 若若Pathij=k:从:从Vi到到Vj 经过经过Vk ,最短路径序列,最短路径序列是是(Vi , , Vk , , Vj) ,则路径子序列,则路径子序列:(Vi , , Vk)和和

591、(Vk , , Vj)一定是一定是从从Vi到到Vk和和从从Vk到到Vj 的的最短路最短路径。从而可以根据径。从而可以根据Pathik和和Pathkj的值再找到的值再找到该路径上所经过的其它顶点该路径上所经过的其它顶点,依此类推依此类推。握福费报躁列树倒此炸瘩砚红疚装鲸讯傍玻勋仲两脚娜齐惰农瘤脱文嫡虫数据结构严蔚敏PPT数据结构严蔚敏PPT 初始化为初始化为Pathij=-1,表示,表示从从Vi到到Vj 不经过任不经过任何何(S中的中的中间中间)顶点顶点。当某个顶点。当某个顶点Vk加入到加入到S中后使中后使Aij变小时变小时,令,令Pathij=k。 表表7-4给出了利用给出了利用Floyd算法

592、求算法求图图7-26的带权有向图的带权有向图的任意一对顶点间的任意一对顶点间最短路径的过程。最短路径的过程。图图7-26 带权有向图及其带权有向图及其邻接邻接矩阵矩阵 0 2 8 0 4 5 0V1482V2V05谅嗜源法蕊迪酪倔机圆柏喷汐氛核制你引泰拿醛典助拇扼巢甚宛痒伸败邪数据结构严蔚敏PPT数据结构严蔚敏PPT 根据上述过程中根据上述过程中Pathij数组数组,得出:得出:V0到到V1 :最短路径是最短路径是 0, 1 ,路径长度是,路径长度是2 ;V0到到V2 :最短路径是最短路径是 0, 1, 2 ,路径长度是,路径长度是6 ;V1到到V0 :最短路径是最短路径是 1, 2, 0 ,

593、路径长度是,路径长度是9 ;表表7-4 用用Floyd算法求任意一对顶点间算法求任意一对顶点间最短路径最短路径 0 2 8 0 45 0 0 2 8 0 4 5 7 0 0 2 6 0 4 5 7 0 0 2 6 9 0 4 5 7 0A -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 1 -1 -1 -1 -1 0 -1 -1 -1 1 2 -1 -1 -1 0 -1PathS 0 0, 1 0, 1, 2 步骤步骤初态初态k=0K=1K=2义走誓兜琳趋另巷叁颗筷乌注峨零钧积叶朱齐舔通柬愧淀发股熄置誊该捂数据结构严蔚敏PP

594、T数据结构严蔚敏PPTV1到到V2 :最短路径是最短路径是 1, 2 ,路径长度是,路径长度是4 ;V2到到V0 :最短路径是最短路径是 2, 0 ,路径长度是,路径长度是5 ;V2到到V1 :最短路径是最短路径是 2, 0, 1 ,路径长度是,路径长度是7 ;算法实现算法实现int AMAX_VEXMAX_VEX ;int PathMAX_VEXMAX_VEX ;void Floyd_path (AdjGraph *G) int j, k, m ; for ( j=0; jvexnum; j+)for ( k=0; kvexnum; k+) Ajk=G-adjjk ; Pathjk=-1 ;

595、 /* 各数组的初始化各数组的初始化 */粉伤衷异邻恃编话犬受牧甜烽嘿橱屏场逾耳必张栖魏奔舱皑汰格与撼还鸵数据结构严蔚敏PPT数据结构严蔚敏PPTfor ( m=0; mvexnum; m+)for ( j=0; jvexnum; j+)for ( k=0; kvexnum; k+) if (Ajm+Amk)Ajk) Ajk=Ajm+Amk ; Pathjk=k ; /* 修改数组修改数组A和和Path的元素值的元素值 */for ( j=0; jvexnum; j+)for ( k=0; kvexnum; k+)if (j!=k) printf(“%d到到%d的最短路径为的最短路径为:n”,

596、 j, k) ; printf(“%d ”,j) ; prn_pass(j, k) ; printf(“%d ”, k) ;本坤腺稗肠爽烯橱忘乓晕甥希夏笋坚圣鞘摇猛坡综联踌死戮痛日怂洪雄址数据结构严蔚敏PPT数据结构严蔚敏PPT printf(“最短路径长度为最短路径长度为: %dn”,Ajk) ; /* end of Floyd */void prn_pass(int j , int k) if (Pathjk!=-1) prn_pass(j, Pathjk) ;printf(“, %d” , Pathjk) ;prn_pass(Pathjk, k) ;威洛霓蹭娄钟谬尼政寺傀帐坤吻五束跨运闪

597、讥虹燕龚测罩许仲宴玻继愚昼数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 七七 分析并回答下列问题:分析并回答下列问题: 图中顶点的度之和与边数之和的关系图中顶点的度之和与边数之和的关系? 有向图中顶点的入度之和与出度之和的关系有向图中顶点的入度之和与出度之和的关系? 具有具有n个顶点的无向图,至少应有多少条边才能个顶点的无向图,至少应有多少条边才能确保是一个连通图确保是一个连通图? 若采用邻接矩阵表示,则该矩若采用邻接矩阵表示,则该矩阵的大小是多少阵的大小是多少? 具有具有n个顶点的有向图,至少应有多少条弧才能个顶点的有向图,至少应有多少条弧才能确保是强连通图的确保是强连通图的? 为什么

598、为什么? 设一有向图设一有向图G=(V,E),其中,其中V=a,b,c,d,e , E=, , , , , , , 郡电肠操塑齿逗噶拽虏责诅辕口憋帝烯怀站润牡淳拇顷宣妙烽言擦痒适岂数据结构严蔚敏PPT数据结构严蔚敏PPT 请画出该有向图,并求各顶点的入度和出度。请画出该有向图,并求各顶点的入度和出度。 分别画出有向图的正分别画出有向图的正邻接链表和逆邻接链表邻接链表和逆邻接链表。 对图对图7-27所示的带权无向图。所示的带权无向图。 写出相应的邻接矩阵表示。写出相应的邻接矩阵表示。 写出相应的边表表示。写出相应的边表表示。 求出各顶点的度。求出各顶点的度。 已知有向图的逆邻接链表如图已知有向图

599、的逆邻接链表如图7-28所示。所示。 画出该有向图。画出该有向图。 写出相应的邻接矩阵表示。写出相应的邻接矩阵表示。 写出从顶点写出从顶点a开始的深度优先和广度优先遍历开始的深度优先和广度优先遍历序列。序列。 画出从顶点画出从顶点a开始的深度优先和广度优先生成开始的深度优先和广度优先生成树。树。猛咬住类仑梳娃烩期熄究立规地箩辅屎靴疽许祈举朝星帛睛赏寞憋蟹屿搁数据结构严蔚敏PPT数据结构严蔚敏PPT1452639682755349图图7-27 带权无向图带权无向图图图7-28 有向图的逆邻接链表有向图的逆邻接链表4 0204 13 22 4 3MAX_VEX-101234v1v2v3v4v5 图

600、图7-29 带权有向图带权有向图V2V4V5V6V110101543061015520V3图图7-30 带权有向图带权有向图adecfb354423956抠疤蟹饯旋挠诸冤凿沤蒋敛梧把陶甄荣感得秋锌惯蛀傅藻集货炼讹水诡礁数据结构严蔚敏PPT数据结构严蔚敏PPT 一个带权连通图的最小生成树是否唯一一个带权连通图的最小生成树是否唯一? ?在什么情在什么情况下可能不唯一况下可能不唯一? ? 对于图对于图7-27所示的带权无向图。所示的带权无向图。 按照按照Prime算法给出从顶点算法给出从顶点2开始构造最小生成开始构造最小生成树的过程树的过程。 按照按照Kruskal算法给出最小生成树的过程算法给出最

601、小生成树的过程。 已知带权有向图已知带权有向图如如图图7-29所示,请利用所示,请利用Dijkstra算算法从顶点法从顶点V4出发到其余顶点的最短路径及长度出发到其余顶点的最短路径及长度,给出相给出相应的求解步骤应的求解步骤。 已知带权有向图已知带权有向图如如图图7-30所示,请利用所示,请利用Floyd算法算法求出每对顶点之间的最短路径及路径长度求出每对顶点之间的最短路径及路径长度。 一个一个AOV网用邻接矩阵表示网用邻接矩阵表示,如图,如图7-31。用拓扑。用拓扑排序求该排序求该AOV网的一个拓扑序列网的一个拓扑序列,给出相应的步骤给出相应的步骤。查樟惹终碘谩澡轨玛驱龟骡二浇适渠住炔榜妊伍

602、白朗记求仕沽昂环焚侈俞数据结构严蔚敏PPT数据结构严蔚敏PPT 拓扑排序的结果不是唯一的,请给出如图拓扑排序的结果不是唯一的,请给出如图7-32所所示的有向图的所有可能的拓扑序列。示的有向图的所有可能的拓扑序列。 请在深度优先搜索算法的基础上设计一个对有向请在深度优先搜索算法的基础上设计一个对有向无环图进行拓扑排序的算法。无环图进行拓扑排序的算法。 设计一个算法利用图的遍历方法输出一个无向图设计一个算法利用图的遍历方法输出一个无向图G中从顶点中从顶点Vi到到Vj的长度为的长度为S的简单路径,设图采用邻接的简单路径,设图采用邻接链表作为存储结构。链表作为存储结构。 假设一个工程的进度计划用假设一

603、个工程的进度计划用AOE网表示网表示,如图,如图7-33所示。所示。 求出每个事件的最早发生时间和最晚发生时间。求出每个事件的最早发生时间和最晚发生时间。 该工程完工至少需要多少时间该工程完工至少需要多少时间? ? 求出所有关键路径和关键活动。求出所有关键路径和关键活动。澄磅郸馅定柑昔讳索屉委无卓与盛莲涌螟寥河肠划翟那滞辕诈扎搪造二寨数据结构严蔚敏PPT数据结构严蔚敏PPT图图7-33 一个一个AOE网网v0v5v4v7v3v2v1v6v8a1=5a2=6a3=3a8=5a4=12a5=3a10=4a9=1a12=5a11=4a6=3a7=3a13=2v9a14=20 1 1 0 0 0 00

604、 0 0 1 1 1 00 0 0 0 1 0 10 0 0 0 0 0 00 0 0 0 0 0 10 0 0 0 0 0 10 0 0 0 0 0 0V0V1V2V3V4V5V6图图7-31 一个一个AOV网的邻接矩阵网的邻接矩阵图图7-32 有向图有向图V3V7V6V5V4V2V1V9V8瑟鞘缆还拾虽臆乃盐殉郴峨酪辅奶惊船盲支字忿藐看敞烟肘舵裁针斌党纬数据结构严蔚敏PPT数据结构严蔚敏PPT第第8章章 动态存储管理动态存储管理 8.1 概述概述 程序执行过程中,程序执行过程中,(数据数据)结构中的每一个数据元素结构中的每一个数据元素都对应一定的存储空间,数据元素的访问都是通过对应都对应一

605、定的存储空间,数据元素的访问都是通过对应的存储单元来进行的。存储空间的分配与管理是由操作的存储单元来进行的。存储空间的分配与管理是由操作系统或编译程序负责实现的,是一个复杂而又重要的问系统或编译程序负责实现的,是一个复杂而又重要的问题,现代的存储管理往往采用动态存储管理思想。题,现代的存储管理往往采用动态存储管理思想。 动态存储管理动态存储管理:如何根据:如何根据“存储请求存储请求”分配分配内存空间?如何内存空间?如何回收回收被释放的被释放的(或不再使用的或不再使用的)内内存空间?存空间? 胸擎滴瞄梅吧夏看颅攻泥彰铂潮爆漫踊阻壤章植各哇普款立咒汰识恕烤兔数据结构严蔚敏PPT数据结构严蔚敏PPT

606、 对于允许进行动态存储分配的程序设计语言,操作对于允许进行动态存储分配的程序设计语言,操作系统在内存中划出一块地址连续的大区域系统在内存中划出一块地址连续的大区域(称为称为堆堆) ,由设计者在程序中利用语言提供的内存动态分配函数由设计者在程序中利用语言提供的内存动态分配函数(如如C的的malloc() ,calloc(),free()函数,函数,C+的的new,delete函数等函数等)来实现对来实现对堆堆的使用。的使用。1 两个基本概念两个基本概念 占用块占用块:已分配给用户使用的一块地址连续的内:已分配给用户使用的一块地址连续的内存区域;存区域; 空闲块空闲块:未曾分配的地址连续的内存区域

607、;:未曾分配的地址连续的内存区域;2 用户请求分配内存用户请求分配内存,系统的处理方式系统的处理方式 当有用户程序进入系统请求分配内存时,系统有两当有用户程序进入系统请求分配内存时,系统有两种处理方式:种处理方式:希判镭全肤簿垄缮朴系耸北丘的戍洲吗点厂鹅妇学膳瘦歉埋叛柿琢哉炼赂数据结构严蔚敏PPT数据结构严蔚敏PPT 系统从高地址空闲块中进行分配,直到分配无法系统从高地址空闲块中进行分配,直到分配无法进行时,才回收所有用户不再使用的空闲块,重新进行时,才回收所有用户不再使用的空闲块,重新组织一个大的空闲块来再分配;组织一个大的空闲块来再分配; 用户程序一旦运行结束,便将它所占内存区释放用户程序

608、一旦运行结束,便将它所占内存区释放成为空闲块,同时,每当新用户请求分配内存时,成为空闲块,同时,每当新用户请求分配内存时,系统需要巡视整个内存区中所有空闲块,并从中找系统需要巡视整个内存区中所有空闲块,并从中找出一个出一个“合适合适”的空闲块分配之。的空闲块分配之。 对于对于的情况,系统需建立一张的情况,系统需建立一张“可利用空间表可利用空间表” 。 程序运行过程中,不断地对堆中的部分区域进行分程序运行过程中,不断地对堆中的部分区域进行分配和释放,堆中会出现占用块和空闲块交错的状态,如配和释放,堆中会出现占用块和空闲块交错的状态,如图图8-1所示。所示。匀役峪轿奎茁赛懦沸锨毛殆蛾弯蒂峻邑刀钮芜

609、狱轮偶廷彦均隶雾槛联港疥数据结构严蔚敏PPT数据结构严蔚敏PPT3 动态存储分配的基本问题动态存储分配的基本问题 当某一时刻用户程序请求分配当某一时刻用户程序请求分配400个字节的存储空间,如何分配个字节的存储空间,如何分配? 将块将块A分配给用户程序分配给用户程序? 从大块从大块C中划出一部分分配给用中划出一部分分配给用户程序户程序? 当某一时刻分配当某一时刻分配B块的用户程序运块的用户程序运行结束,行结束,B块要进行回收,如何回收块要进行回收,如何回收? B块直接回收并成为一个独立的块直接回收并成为一个独立的空闲块空闲块? B块回收并和前、后的空闲块块回收并和前、后的空闲块A、C合并后形成

610、一个更大的空闲块合并后形成一个更大的空闲块?ACB12196H11000H12004H12240H130EFH图图8-1 堆的状态堆的状态叁蘑鸭虱同难稍荔变尤骨旗锌折沁潞舍沼武酚卜缚鸥惰淖蚕枉频龄感兢浓数据结构严蔚敏PPT数据结构严蔚敏PPT8.2 可利用空间表及分配方法可利用空间表及分配方法 可利用空间表中包含所有可分配的空闲块,当用户可利用空间表中包含所有可分配的空闲块,当用户请求分配时,系统从可利用空间表中删除一个结点分配请求分配时,系统从可利用空间表中删除一个结点分配之;当用户释放其所占内存时,系统即回收并将它插入之;当用户释放其所占内存时,系统即回收并将它插入到可利用空间表中。因此,

611、可利用空间表亦称做到可利用空间表中。因此,可利用空间表亦称做“存储存储池池”。史愈球晨帕浸阜褐侗矗赛陪靛处泥叮爽始径遁缅峙普俺淋境昭骡滩序韦旭数据结构严蔚敏PPT数据结构严蔚敏PPT8.2.1 可利用空间表的组织可利用空间表的组织 可用空间表的组织有两种方式:目录表方式和链表可用空间表的组织有两种方式:目录表方式和链表方式,如图方式,如图8-2所示所示 。动态存储管理中需要不断地进行。动态存储管理中需要不断地进行空闲块的分配和释放,对目录表来说管理复杂,因此,空闲块的分配和释放,对目录表来说管理复杂,因此,可利用空间表通常以链表方式组织可利用空间表通常以链表方式组织 。 当可利用空间表以链表方

612、式组织时,每个空闲块就当可利用空间表以链表方式组织时,每个空闲块就是链表中的一个结点。是链表中的一个结点。 分配时:从链表中找到一个合适的结点加以分配,分配时:从链表中找到一个合适的结点加以分配,然后将该结点删除之;然后将该结点删除之; 回收时:将空闲块插入到链表中。回收时:将空闲块插入到链表中。 实际的动态存储管理实施时,具体的分配和释放的实际的动态存储管理实施时,具体的分配和释放的策略取决于结点策略取决于结点( (空闲块空闲块) )的结构。的结构。房花屈给疤鹏爱底眺若近巢墅遣阑邮摘父壶韧寥吠肿酥卜娥瘤糯公邻竣腻数据结构严蔚敏PPT数据结构严蔚敏PPT(a) 堆的状态堆的状态13196H11

613、000H12004H13740H160EFH00000H216EFH326EFH起始地址起始地址 空闲块大小空闲块大小 使用情况使用情况12004H 4498 空闲空闲13740H 10671 空闲空闲216EFH 69632 空闲空闲(b) 目录表方式目录表方式0 4498 0 10671 0 69632 av(c) 链表方式链表方式图图8-2 动态存储管理过程中的内存状态和空闲表结构动态存储管理过程中的内存状态和空闲表结构偏嘱阵缄籍脉羡抚虎当单阿啤悲摹城运择砷杀漳呕论磊勇矫永茄锄谨耶航数据结构严蔚敏PPT数据结构严蔚敏PPT8.2.2 结点结构方式与分配策略结点结构方式与分配策略1 请求分

614、配的块大小相同请求分配的块大小相同 将进行动态存储分配的整个内存区域将进行动态存储分配的整个内存区域(堆堆)按所需大按所需大小分割成若干大小相同的块,然后用指针链接成一个可小分割成若干大小相同的块,然后用指针链接成一个可利用空间表。利用空间表。 分配时:从表的首结点分配,然后删除该结点;分配时:从表的首结点分配,然后删除该结点; 回收时:将释放的空闲块插入表头。回收时:将释放的空闲块插入表头。2 请求分配的块大小只有几种规格请求分配的块大小只有几种规格 根据统计概率事先对动态分配的堆建立若干个可利根据统计概率事先对动态分配的堆建立若干个可利用空间链表,同一链表中的结点用空间链表,同一链表中的结

615、点(块块)大小都相同。大小都相同。饱卓搪裂窥圭腻弃热寒叔闹遗梧龄疥捶骨骚佑皂佐绸澳颗忌迎煽纳美辱侈数据结构严蔚敏PPT数据结构严蔚敏PPT 分配时分配时:根据请求的大小:根据请求的大小,将最接近该大小的某,将最接近该大小的某个链表的首结点分配给用户。若剩余部分正好差不个链表的首结点分配给用户。若剩余部分正好差不多是另一种规格大小,则将剩余部分插入到另一种多是另一种规格大小,则将剩余部分插入到另一种规格的链表中,然后删除该结点规格的链表中,然后删除该结点; 回收时回收时:只要:只要将所释放的空闲块插入到相应大小将所释放的空闲块插入到相应大小的表头。的表头。存在的问题存在的问题: 当请求分配的块空

616、间大小比最大规格的结点还大时当请求分配的块空间大小比最大规格的结点还大时,分配不能进行分配不能进行。而实际上而实际上内存空间内存空间却却可能存在比所需大可能存在比所需大小还要大的的连续空间,小还要大的的连续空间,应该能够分配应该能够分配。忍珊卯家佩柜妥谩九互栗育洒映钦寨屠价告痈碴辕蚤蛆胀值盲瑰七收涵拯数据结构严蔚敏PPT数据结构严蔚敏PPT3 3 请求分配的块大小不确定请求分配的块大小不确定 系统开始时,整个堆空间是一个空闲块,链表中只系统开始时,整个堆空间是一个空闲块,链表中只有一个大小为整个堆的结点,随着分配和回收的进行,有一个大小为整个堆的结点,随着分配和回收的进行,链表中的结点大小和个

617、数动态变化。链表中的结点大小和个数动态变化。 由于链表中结点大小不同,结点中除标志域和链域由于链表中结点大小不同,结点中除标志域和链域之外,尚需有一个结点大小域之外,尚需有一个结点大小域(size),以保存空闲块的,以保存空闲块的大小,如大小,如图图8-2(b)。 问题问题:若用户请求分配大小为若用户请求分配大小为n(kB)的内存,而链的内存,而链表中有若干大小不小于表中有若干大小不小于n的空闲块时,如何分配的空闲块时,如何分配?有有3种种分配策略分配策略。惜登厚宪盲棕租筹晋公卿蒜池痹晨佐养绢砂施死躺槽惋穷附语咖可洁蟹瓢数据结构严蔚敏PPT数据结构严蔚敏PPT 首次拟合法首次拟合法(First

618、 fit) 分配时分配时:从表头指针开始查找可利用空间表,将从表头指针开始查找可利用空间表,将找到的第一个不小于找到的第一个不小于n的空闲块的部分的空闲块的部分( (所需要大小所需要大小) )分配给用户,剩下部分仍然是一个空闲块结点;分配给用户,剩下部分仍然是一个空闲块结点; 回收时回收时:将释放的空闲块插入在链表的表头。将释放的空闲块插入在链表的表头。特点特点:分配时随机的;回收时仅需插入到表头。分配时随机的;回收时仅需插入到表头。 最佳拟合法最佳拟合法(Best fit) 分配时分配时:扫描整个:扫描整个可利用空间链表,找到一个大可利用空间链表,找到一个大小满足要求且最接近小满足要求且最接

619、近n空闲块,将其中的一部分空闲块,将其中的一部分( (所所需要大小需要大小) )分配给用户,剩下部分仍然是一个空闲块分配给用户,剩下部分仍然是一个空闲块结点;结点;播惜靖繁化拦锥伤掖止瘁病萍恋瑶皇险俊堰吕丧板阔朝象匈杭裁族魔悬交数据结构严蔚敏PPT数据结构严蔚敏PPT 回收时回收时:只要将释放的空闲块插入到链表的合适只要将释放的空闲块插入到链表的合适位置。位置。 为了使分配时不需要扫描整个可利用空间链表,链为了使分配时不需要扫描整个可利用空间链表,链表组织表组织( (块回收时块回收时) )成成按从小到大排序按从小到大排序( (升序升序) ) 。优点优点:适用于请求分配的内存块大小范围较广的系统

620、;适用于请求分配的内存块大小范围较广的系统;缺点缺点:系统容易产生无法分配的内存碎片;无论分配系统容易产生无法分配的内存碎片;无论分配与回收,都需要查找表,最费时;与回收,都需要查找表,最费时; 最差拟合法最差拟合法(Worst fit) 分配时分配时:扫描整个:扫描整个可利用空间链表,找到一个大可利用空间链表,找到一个大小最大的空闲块,将其中的一部分小最大的空闲块,将其中的一部分( (所需要大小所需要大小) )分配分配给用户,剩下部分仍然是一个空闲块结点;给用户,剩下部分仍然是一个空闲块结点;狱檬臆却蛙圈士仁富聋粪肺芒皑杜霓替疑绍划嘿臆漱踢锭乙琶吵玄震纫甭数据结构严蔚敏PPT数据结构严蔚敏P

621、PT 回收时回收时:只要将释放的空闲块插入到链表的合适只要将释放的空闲块插入到链表的合适位置。位置。 为了使分配时不需要扫描整个可利用空间链表,链为了使分配时不需要扫描整个可利用空间链表,链表组织表组织( (块回收时块回收时) )成成按从大到小按从大到小排序排序( (降序降序) ) 。特点特点:适用于请求分配的内存块的大小范围较窄的系适用于请求分配的内存块的大小范围较窄的系统;分配无需查找,回收需要查找适当的位置。统;分配无需查找,回收需要查找适当的位置。4 4 选择分配策略需考虑的因素选择分配策略需考虑的因素 用户的逻辑要求、请求分配量的大小分布、分配和用户的逻辑要求、请求分配量的大小分布、

622、分配和释放的频率以及效率对系统的重要性。释放的频率以及效率对系统的重要性。袋诀卤凶缀素杏行悸冤毗蠢兽绍淌沛菩拟呻服汉鸥市抗飞殴塞鞋尧侯挪诱数据结构严蔚敏PPT数据结构严蔚敏PPT8.3 边界标识法边界标识法 边界标识法边界标识法(Boundary Tag Method)是操作系统中是操作系统中一种常用的进行动态分配的存储管理方法。一种常用的进行动态分配的存储管理方法。 系统将所有的空闲块链接成一个双重循环链表,分系统将所有的空闲块链接成一个双重循环链表,分配可采用几种方法配可采用几种方法(前述前述) 。系统的特点系统的特点 每个内存区域的头部和底部两个边界上分别设置标每个内存区域的头部和底部两

623、个边界上分别设置标识,以标识该区域为占用块或空闲块,在回收块时易于识,以标识该区域为占用块或空闲块,在回收块时易于判别在物理位置上与其相邻的内存区域是否为空闲块,判别在物理位置上与其相邻的内存区域是否为空闲块,以便于将所有地址连续的空闲存储区合并成一个尽可能以便于将所有地址连续的空闲存储区合并成一个尽可能大的空闲块。大的空闲块。嘻笨矮已饿押买石幻梁雍簇似眼拍搂奎勉楼恭疲翠翟漱精疟挖饰沂邵焊祖数据结构严蔚敏PPT数据结构严蔚敏PPT8.3.1 可利用空闲表结点结构可利用空闲表结点结构Llink tag size rlinkuplink tag spaceheadfoottypedef struc

624、t word Union struct word *llink;struct word *uplink; ;int tag;int size;struct word *rlink;OtherType other;WORD, head, foot, *Space;#define FootLoc(p) p+p-size-1麻酉菌硕的蓑镀庐婉喝鸦介饥遥磊锌笨郝拾善量甭躁剿窒忧子直联堵侈幸数据结构严蔚敏PPT数据结构严蔚敏PPT8.3.2 分配算法分配算法 分配算法比较简单,可采用前述三种方法中的任一分配算法比较简单,可采用前述三种方法中的任一种进行分配。设采用首次拟合法,为了使系统更有效地种进行分配

625、。设采用首次拟合法,为了使系统更有效地运行,在边界标识法中还做了两条约定:运行,在边界标识法中还做了两条约定: 选定适当常量选定适当常量e,设待分配空闲块,设待分配空闲块、请求分配空、请求分配空间的大小分别为间的大小分别为m 、 n 。 当当m-ne时:将整个空闲块分配给用户;时:将整个空闲块分配给用户; 当当m-ne时:则只分配请求的大小时:则只分配请求的大小n给用户;给用户;作用作用:尽量减少空闲块链表中出现小碎片尽量减少空闲块链表中出现小碎片(容量容量e) ,提高分配效率;减少对空闲块链表的维护工作量。为了提高分配效率;减少对空闲块链表的维护工作量。为了避免修改指针,约定将高地址部分分配

626、给用户。避免修改指针,约定将高地址部分分配给用户。悄酗但轮柜孜裹矣似谗膛轿鲸哉坠奸囊嫌治捡翱番撬账馆殊若胁崩娄扶弃数据结构严蔚敏PPT数据结构严蔚敏PPT 空闲块链表中的结点数可能很多,为了提高查找空闲块链表中的结点数可能很多,为了提高查找空闲块的速度和防止小容量结点密集,每次查找时从空闲块的速度和防止小容量结点密集,每次查找时从不同的结点开始不同的结点开始上次刚分配结点的后继结点开始。上次刚分配结点的后继结点开始。Space AllocBoundTag( Space *pav, int n ) p = pav ; for ( ; p &p-sizerlink!=pav; p=p-rlink

627、)if ( !p | p-sizerlink ; if ( p-sizenllink=p-link ; p-llink-rlink=pav ; p-tag=f-tag=1 ; else f-tag=1 ; p-size-=n ; f= FootLoc( p ) ; f-tag= 0 ; f-uplink=p ; p=f+1; p-tag=1 ; p-size=n ; return p ; 抨牲捎馒概画卒删冗诽菌脑于绩皋喘婚掖巍孵滁牡源旨歪庄武米憨长古陶数据结构严蔚敏PPT数据结构严蔚敏PPT8.3.3 回收算法回收算法 当用户释放占用块,系统需立即回收以备新的请求当用户释放占用块,系统需立即回

628、收以备新的请求产生时进行再分配。关键的是使物理地址毗邻的空闲块产生时进行再分配。关键的是使物理地址毗邻的空闲块合并成一个尽可能大的结点,则需检查刚释放的占用块合并成一个尽可能大的结点,则需检查刚释放的占用块的左、右紧邻是否为空闲块。的左、右紧邻是否为空闲块。 假设所释放的块的头地址为假设所释放的块的头地址为p,则与其低地址紧邻,则与其低地址紧邻的块的底部地址为的块的底部地址为p-1;与其高地址紧邻的块的头地址;与其高地址紧邻的块的头地址为为p+p-size,它们中的标志域就表明了两个相邻块的使,它们中的标志域就表明了两个相邻块的使用状况:用状况: 若若(p-1)-tag=0 :则左邻块为空闲块

629、;:则左邻块为空闲块; 若若(p+p-size)-tag=0 :则右邻块为空闲块;:则右邻块为空闲块;回收算法需要考虑的回收算法需要考虑的4种情况:种情况:化讯尤炮没灸两赦盛接戍孔患锗债抒胡臻惧揽蹬颂惊迭屡看北粤魏肇埋死数据结构严蔚敏PPT数据结构严蔚敏PPT 释放块的左、右邻块均为占用块释放块的左、右邻块均为占用块 将被释放块简单地插入到空闲块链表中即可。将被释放块简单地插入到空闲块链表中即可。p-tag=0 ; FootLoc(p)-uplink=p ; FootLoc(p)-tag=0 ;if ( !pav ) pav=p-llink=p-rrlink=p ;else q=pav-lli

630、nk ; P-rlink=pav ; p-llink=q ; q-rlink=pav-llink=p ;Pav=p ; 冗聪抉谨娶亢瑚覆饵赣翁湿必癌许壹汤裔拜勤菜扦陷绸辨料森漂啊陵曳挫数据结构严蔚敏PPT数据结构严蔚敏PPT 释放块的左邻块空闲而右邻块为占用释放块的左邻块空闲而右邻块为占用 和左邻块合并成一个大的空闲块结点,改变左邻块和左邻块合并成一个大的空闲块结点,改变左邻块的的size域及重新设置域及重新设置(合并后合并后)结点的底部。结点的底部。n=p-size ; s=(p-1)-uplink ; s-size+=n;f=p+n1 ; f-uplink=s ; f-tag=0 ; 释放

631、块的左邻占用而右邻空闲释放块的左邻占用而右邻空闲 和右邻块合并成一个大的空闲块结点,改变右邻块和右邻块合并成一个大的空闲块结点,改变右邻块的的size域及重新设置域及重新设置(合并后合并后)结点的头部。结点的头部。t=p+p-size ; p-tag=0 ; q=t-llink ; p-llink=q ; q-rlink=p ; q1=t-rlink ; p-rlink=q1 ; q1-llink=p ; p-size+=t-size ; FootLoc(t)-uplink=p ;丢器灿费抠镁役记寞拨柯芍毋恕疙晤疥俞朝闲器搐使荒摔汇乏领慢堵巡贾数据结构严蔚敏PPT数据结构严蔚敏PPT 释放块的

632、左、右邻释放块的左、右邻块块均为空闲块均为空闲块 和左、右邻块合并成一个大的空闲块结点,改变左和左、右邻块合并成一个大的空闲块结点,改变左邻块的邻块的size域及重新设置域及重新设置(合并后合并后)结点的底部。结点的底部。n=p-size ; s=(p-1)-uplink ; t=p+p-size ; s-size+=n+t-size ; q=t-llink ; q1=t-rlink ;q-rlink=q1 ; q1-llink=q ; FootLoc(t)-uplink=s;堰专哇剂驹奶官孕澜及纽珊晶躬吧拭仍俘怀搔贴捷汽岂厕沼耶彪扁袜慷进数据结构严蔚敏PPT数据结构严蔚敏PPT8.4 伙伴系

633、统伙伴系统 伙伴系统是一种非顺序内存管理方法,不是以顺伙伴系统是一种非顺序内存管理方法,不是以顺序片段来分配内存,是把内存分为两个部分,只要有可序片段来分配内存,是把内存分为两个部分,只要有可能,这两部分就可以合并在一起能,这两部分就可以合并在一起; 且这两部分从来不是且这两部分从来不是自由的,程序可以使用伙伴系统中的一部分或者两部分自由的,程序可以使用伙伴系统中的一部分或者两部分都不使用。与边界标识法类似,所不同是:无论都不使用。与边界标识法类似,所不同是:无论占用块占用块或空闲块或空闲块,其,其大小均为大小均为2的的k次幂次幂。赢裔励付矢霖烃膛哪绷矛盟那重蔓氏侨吻呆颅龄役淌常拙盯贰羚善二舟

634、毋数据结构严蔚敏PPT数据结构严蔚敏PPT8.4.1 可利用空间表的结构可利用空间表的结构 为了再分配时查找方便起见,我们将所有大小相同为了再分配时查找方便起见,我们将所有大小相同的空闲块建于一张子表中。每个子表是一个双重链表,的空闲块建于一张子表中。每个子表是一个双重链表,这样的链表可能有这样的链表可能有m+1个,将这个,将这m+1个表头指针用向量个表头指针用向量结构组织成一个表,这就是伙伴系统的可利用空间表。结构组织成一个表,这就是伙伴系统的可利用空间表。 可利用空间表的数据类型描述如下:可利用空间表的数据类型描述如下:曲凹咕慧挣雨后围进犬限回住毋趟额织辩岭线痹臣崔瞄瑟胜摆曾是挤抛酝数据结

635、构严蔚敏PPT数据结构严蔚敏PPT#define M 16typedef struct WORD_b WORD_b * llink; /* 前驱结点前驱结点 */int tag; /* 使用标识使用标识 */int kval; /* 块的大小块的大小,是是2的幂次的幂次 */WORD_b *rlink; /* 后继结点后继结点 */OtherType other; WORD_b, head; typedef struct HeadNode int nodesize;WORD_b * first;FreeListM+1;艇歇选扔爹撤啤美摹糙犀辛公长谜低售皮雅哲铆缨倪巨整陀幕僳和忆兆藏数据结构严蔚

636、敏PPT数据结构严蔚敏PPT8.4.2 分配算法分配算法 当程序提出大小为当程序提出大小为n的内存分配请求时,首先的内存分配请求时,首先在可在可利用表中利用表中查找大小与查找大小与n相匹配的子表相匹配的子表.1 算法思想算法思想 若存在若存在2k-1n2k-1的空闲子表结点:则将子表中的空闲子表结点:则将子表中的任意一个结点分配之;的任意一个结点分配之; 若不存在若不存在2k-1n2k-1的空闲子表结点:则从结点的空闲子表结点:则从结点大小为大小为2k的子表中找到一个空闲结点,将其中的子表中找到一个空闲结点,将其中一半一半分分配给程序,剩余的配给程序,剩余的一半一半插入到结点大小为插入到结点大

637、小为2k-1的子表的子表中。中。雄曲了默采缔告阎紊匆沿置狰温诺条尘乎城竿沦篓叮酪杉窒靡蔚识把睡丘数据结构严蔚敏PPT数据结构严蔚敏PPT2 说明说明 在进行大小为在进行大小为n(2k-i-1n2k-i-1,i=1,2,k-1) 的内存的内存分配请求时,若所有小于分配请求时,若所有小于2k的子表均为空的子表均为空(没有空闲结没有空闲结点点),则同样需要从大小为,则同样需要从大小为2k的子表中找到一个空闲结的子表中找到一个空闲结点,点,将其中将其中2k-i一小部分分配一小部分分配给用户,而将给用户,而将剩余部分分割剩余部分分割成若干个结点分别插入对应的子表成若干个结点分别插入对应的子表。投泅螟昧杠

638、车掉个欧谭捍勒扭桂库霞摆诀廖变馅火劣抽蔼兹谅茄校臼溯找数据结构严蔚敏PPT数据结构严蔚敏PPT8.4.3 回收算法回收算法 当程序释放所占用的块时,系统将该新的空闲块插当程序释放所占用的块时,系统将该新的空闲块插入到可利用空闲表中,需要考虑合并成大块问题。在伙入到可利用空闲表中,需要考虑合并成大块问题。在伙伴系统中,只有伴系统中,只有“互为伙伴互为伙伴”的两个子块均空闲时才合的两个子块均空闲时才合并并;即使有两个相邻且大小相同的空闲块,如果不是;即使有两个相邻且大小相同的空闲块,如果不是“互为伙伴互为伙伴” (从同一个大块中分裂出来的从同一个大块中分裂出来的)也不合并。也不合并。1 伙伴空闲块

639、的确定伙伴空闲块的确定 设设p是大小为是大小为2k的空闲块的首地址,且的空闲块的首地址,且p MOD 2k+1 =0,则首地址为,则首地址为p和和p+2k的两个空闲块的两个空闲块“互为伙伴互为伙伴”。首地址为首地址为p大小为大小为2k的内存块的,其伙伴的首地址为:的内存块的,其伙伴的首地址为: buddy(p,k)=p+2k 若若p MOD 2k+1 =0P-2k 若若p MOD 2k+1 =2k殃秆呕楼羹凛兆础仗鸭搪疫帮慈蒂碑淑总阶规声故赠嵌月牡修形栽免顶再数据结构严蔚敏PPT数据结构严蔚敏PPT2 回收算法回收算法 设要回收的空闲块的首地址是设要回收的空闲块的首地址是p,其大小为,其大小为

640、2k的,的,算法思想是:算法思想是: 判断其判断其 “互为伙伴互为伙伴”的两个空闲块是否为空:的两个空闲块是否为空:若不为空,仅将要回收的空闲块直接插入到相应的子若不为空,仅将要回收的空闲块直接插入到相应的子表中;否则转表中;否则转; 按以下步骤进行空闲块的合并:按以下步骤进行空闲块的合并: 在相应子表中找到其伙伴并删除之;在相应子表中找到其伙伴并删除之; 合并两个空闲块;合并两个空闲块; 重复重复,直到合并后的空闲块的伙伴不是空闲块,直到合并后的空闲块的伙伴不是空闲块为止。为止。系统的特点系统的特点:算法简单;速度快;但容易产生碎片。算法简单;速度快;但容易产生碎片。旨装巧嗣俯书慈唯刽瞄踌肌

641、昭碗吃曝败纶智晌谁租挨拘锨禄女陌贮恭唆秽数据结构严蔚敏PPT数据结构严蔚敏PPT第第9章章 查找查找 数据的组织和查找是大多数应用程序的核心,而数据的组织和查找是大多数应用程序的核心,而查找是所有查找是所有数据处理数据处理中最基本、中最基本、最常用的操作最常用的操作。特别当。特别当查找的对象是一个庞大数量的数据集合中的元素时,查查找的对象是一个庞大数量的数据集合中的元素时,查找的方法和效率就显得格外重要。找的方法和效率就显得格外重要。 本章主要讨论顺序表、有序表、树表和哈希表查找本章主要讨论顺序表、有序表、树表和哈希表查找的各种实现方法,以及相应查找方法在等概率情况下的的各种实现方法,以及相应

642、查找方法在等概率情况下的平均查找长度。平均查找长度。摩挝窄达耿雏胸磅蹈总郴斌唇升蹲详芽根霍妻悔灿苍灸至帐于欠绑据铆兽数据结构严蔚敏PPT数据结构严蔚敏PPT9.1 查找的概念查找的概念 查找表查找表(Search Table):相同类型的数据元素相同类型的数据元素(对象对象)组成的集合,每个元素通常由若干数据项构成。组成的集合,每个元素通常由若干数据项构成。 关键字关键字(Key,码,码):数据元素中某个数据元素中某个(或几个或几个)数数据项的值,它可以标识一个数据元素。若关键字能据项的值,它可以标识一个数据元素。若关键字能唯一唯一标识一个数据元素,则关键字称为标识一个数据元素,则关键字称为主

643、关键字主关键字;将能标识;将能标识若干个数据元素的关键字称为若干个数据元素的关键字称为次关键字次关键字。 查找查找/检索检索(Searching):根据给定的根据给定的K值,在查值,在查找表中确定一个关键字等于给定值的记录或数据元素。找表中确定一个关键字等于给定值的记录或数据元素。 查找表中查找表中存在存在满足条件的记录:查找成功;结果:满足条件的记录:查找成功;结果:所查到的记录信息或记录在查找表中的位置。所查到的记录信息或记录在查找表中的位置。 查找表中查找表中不存在不存在满足条件的记录:查找失败。满足条件的记录:查找失败。附次睛雀死课寡兄展帮陕臃忘杖镊栋张兼硫镑袜握躬靶搽朔达榜荔推挡烷数

644、据结构严蔚敏PPT数据结构严蔚敏PPT查找有两种基本形式:静态查找和动态查找。查找有两种基本形式:静态查找和动态查找。 静态查找静态查找(Static Search):在查找时只对在查找时只对数据元素进行查询或检索,查找表称为静态查找表。数据元素进行查询或检索,查找表称为静态查找表。 动态查找动态查找(Dynamic Search):在实施查找的在实施查找的同时,插入查找表中不存在的记录,或从查找表中删除同时,插入查找表中不存在的记录,或从查找表中删除已存在的某个记录,查找表称为动态查找表。已存在的某个记录,查找表称为动态查找表。 查找的对象是查找表,采用何种查找方法,首先取查找的对象是查找表

645、,采用何种查找方法,首先取决于查找表的组织。查找表是记录的集合,而集合中的决于查找表的组织。查找表是记录的集合,而集合中的元素之间是一种完全松散的关系,因此,元素之间是一种完全松散的关系,因此,查找表是一种查找表是一种非常灵活的数据结构非常灵活的数据结构,可以用多种方式来存储可以用多种方式来存储。 根据存储结构的不同,查找方法可分为三大类:根据存储结构的不同,查找方法可分为三大类:反棚法胆邯滁壤败稚惧各搏刻秸蹿显正荆瓢键授注亭龚耀菱选殴度洛沃周数据结构严蔚敏PPT数据结构严蔚敏PPT 顺序表和链表的查找顺序表和链表的查找:将给定的:将给定的K值与查找表中值与查找表中记录的关键字记录的关键字逐个

646、进行比较逐个进行比较, 找到要查找的记录;找到要查找的记录; 散列表的查找散列表的查找:根据给定的:根据给定的K值值直接访问直接访问查找表,查找表, 从而找到要查找的记录;从而找到要查找的记录; 索引查找表的查找索引查找表的查找:首先根据索引确定待查找记:首先根据索引确定待查找记录所在的块录所在的块 ,然后再从块中找到要查找的记录。,然后再从块中找到要查找的记录。查找方法评价指标查找方法评价指标 查找过程中主要操作是关键字的比较,查找过程中查找过程中主要操作是关键字的比较,查找过程中关键字的关键字的平均比较次数平均比较次数(平均查找长度平均查找长度ASL:Average Search Leng

647、th)作为衡量一个查找算法效率高低的标准。作为衡量一个查找算法效率高低的标准。ASL定义为:定义为:ASL= Pi Ci n为查找表中记录个数为查找表中记录个数i=1n Pi=1i=1n荚佰贮察雌糙栅苛父刷珐贴连盈套辅柿滩佰歹臂巧争极豹男御碌穴佛橱秤数据结构严蔚敏PPT数据结构严蔚敏PPT其中:其中:Pi :查找第:查找第i个记录的概率,不失一般性,认为查个记录的概率,不失一般性,认为查找每个记录的概率相等,即找每个记录的概率相等,即P1=P2=Pn=1/n ;Ci:查找第:查找第i个记录需要进行比较的次数。个记录需要进行比较的次数。 一般地,认为记录的关键字是一些可以进行比较运一般地,认为记

648、录的关键字是一些可以进行比较运算的类型,如整型、字符型、实型等,本章以后各节中算的类型,如整型、字符型、实型等,本章以后各节中讨论所涉及的关键字、数据元素等的类型描述如下:讨论所涉及的关键字、数据元素等的类型描述如下: 典型的关键字类型说明是:典型的关键字类型说明是:typedef float KeyType ; /* 实型实型 */typedef int KeyType ; /* 整型整型 */typedef char KeyType ; /* 字符串型字符串型 */ 数据元素类型的定义是:数据元素类型的定义是:俘重匠劫惦终募跋需蹿层镐游绝篮鞋钮葫揍巷析咯拄淘测崩型峦隙损亚恶数据结构严蔚敏P

649、PT数据结构严蔚敏PPTtypedef struct RecType KeyType key ; /* 关键字码关键字码 */ /* 其他域其他域 */RecType ; 对两个关键字的比较约定为如下带参数的宏定义:对两个关键字的比较约定为如下带参数的宏定义:/* 对数值型关键字对数值型关键字 */#define EQ(a, b) (a)=(b)#define LT(a, b) (a)(b)#define LQ(a, b) (a)=(b)/* 对字符串型关键字对字符串型关键字 */#define EQ(a, b) (!strcmp(a), (b) )#define LT(a, b) (strc

650、mp(a), (b)0 )#define LQ(a, b) (strcmp(a), (b)High),查找失败。,查找失败。2 算法实现算法实现援痹搂酞数态森邱逢铬狙旁知柄撼勾急压请闰擞澡拉挚蠕胖誊钠任敲辫淹数据结构严蔚敏PPT数据结构严蔚敏PPTint Bin_Search(SSTable ST , KeyType key) int Low=1,High=ST.length, Mid ;while (Low50)时,时, ASL 2(n+1)-1。姆叁锋买肋夺拳隆痹舷根裕猛僵卸忌垦赤抄损韦伤叭险瘪差琉醋贾娩棵辈数据结构严蔚敏PPT数据结构严蔚敏PPT9.2.3 分块查找分块查找 分块查找分块

651、查找(Blocking Search)又称索引顺序查找,又称索引顺序查找,是前面两种查找方法的综合。是前面两种查找方法的综合。1 查找表的组织查找表的组织 将查找表分成几块。块间有序,即第将查找表分成几块。块间有序,即第i+1块的所有块的所有记录关键字均大于记录关键字均大于(或小于或小于)第第i块记录关键字;块内块记录关键字;块内无序。无序。 在查找表的基础上附加一个索引表,索引表是按在查找表的基础上附加一个索引表,索引表是按关键字有序的,索引表中记录的构成是:关键字有序的,索引表中记录的构成是:最大关键字最大关键字起始指针起始指针戒猾彪增银瘫纪皑赎阐断滓啃狙甥燎兹醇瘁母瞻中碟吼魄臂缉梆顽逃疗

652、忽数据结构严蔚敏PPT数据结构严蔚敏PPT2 查找思想查找思想 先确定待查记录所在块,再在块内查找先确定待查记录所在块,再在块内查找(顺序查找顺序查找)。3 算法实现算法实现typedef struct IndexType keyType maxkey ; /* 块中最大的关键字块中最大的关键字 */int startpos ; /* 块的起始位置指针块的起始位置指针 */Index;镁夫句铸喉啊盼辽剐侄燥歹凉颇贮性婴绊纹蔑搂较并挤蓟击沥稗富联蹲敖数据结构严蔚敏PPT数据结构严蔚敏PPTint Block_search(RecType ST , Index ind , KeyType key

653、, int n , int b) /* 在分块索引表中查找关键字为在分块索引表中查找关键字为key的记录的记录 */ /*表长为表长为n ,块数为,块数为b */ int i=0 , j , k ;while (ib) printf(nNot found); return(0); j=indi.startpos ;while (jn|!EQ(STj.key, key) ) j=0; printf(nNot found); return(j); 4 算法示例算法示例索引表索引表1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1822 12 13 8 9 20

654、33 42 44 38 24 48 60 58 74 57 86 53查查3822 48 86 1 7 13图图9-3 分块查找示例分块查找示例瘤鲜扯铆帕驳诅闰服兵跪藉榔灌踞躺乒恿垮牡牛槐呵醋韶印尔乐痞扳邦像数据结构严蔚敏PPT数据结构严蔚敏PPT5 算法分析算法分析 设表长为设表长为n个记录,均分为个记录,均分为b块,每块记录数为块,每块记录数为s,则,则b= n/s 。设记录的查找概率相等,每块的查找概率为。设记录的查找概率相等,每块的查找概率为1/b,块中记录的查找概率为,块中记录的查找概率为1/s,则,则平均查找长度平均查找长度ASL:ASL=Lb+Lw= j+j=1b i=i=1ss

655、12b+12s+1+绍叔怨锰庙看前隆晦辫镶毁丫暇添镐谷跑文拭瓷睦拼酌洽苛息铲溅迂帽梧数据结构严蔚敏PPT数据结构严蔚敏PPT9.2.4 Fibonacci查找查找 Fibonacci查找方法是根据查找方法是根据Fibonacci数列的特点对查数列的特点对查找表进行分割。找表进行分割。Fibonacci数列的定义是:数列的定义是: F(0)=0,F(1)=1,F(j)=F(j-1)+F(j-2) 。1 查找思想查找思想 设查找表中的记录数比某个设查找表中的记录数比某个Fibonacci数小数小1,即设,即设n=F(j)-1。用。用Low、High和和Mid表示待查找区间的下界、表示待查找区间的下

656、界、上界和分割位置,初值为上界和分割位置,初值为Low=1,High=n。 取分割位置取分割位置Mid:Mid=F(j-1) ; 比较比较分割位置记录的关键字与给定的分割位置记录的关键字与给定的K值:值:青织娠瑚总拭幅陛脚题荔斩矩烩茅峪损王诡舞挝精锯纹案酣隶哄湾啸普刘数据结构严蔚敏PPT数据结构严蔚敏PPT 相等相等: 查找成功;查找成功; 大于大于:待查记录在区间的前半段:待查记录在区间的前半段(区间长度为区间长度为F(j-1)-1),修改上界指针:,修改上界指针: High=Mid-1,转,转 ; 小于小于:待查记录在区间的后半段:待查记录在区间的后半段(区间长度为区间长度为F(j-2)-

657、1),修改下界指针:,修改下界指针:Low=Mid+1,转,转 ;直到越界直到越界(LowHigh),查找失败。,查找失败。2 算法实现算法实现 在算法实现时在算法实现时,为了避免频繁计算,为了避免频繁计算Fibonacci数,可数,可用两个变量用两个变量f1和和f2保存当前相邻的两个保存当前相邻的两个Fibonacci数,这数,这样在以后的计算中可以依次递推计算出。样在以后的计算中可以依次递推计算出。五肆腑肯甥争念愚洋朔秧密洽堆便赋蔡桔叭肤诣廖淳个耶膏硬阐害尾煮馒数据结构严蔚敏PPT数据结构严蔚敏PPTint fib(int n) int i, f , f0=0 , f1=1 ;if (n=

658、0) return(0) ;if (n=1) return(1) ;for (i=2 ; i=n ; i+ ) f=f0+f1 ; f0=f1 ; f1=f ; return(f) ;int Fib_search(RecType ST , KeyType key , int n) /* 在有序表在有序表ST中用中用Fibonacci方法查找关键字为方法查找关键字为key的记录的记录 */ int Low=1, High, Mid, f1, f2 ;High=n ; f1=fib(n-1) ; f2=fib(n-2) ;while (Lowkey, key) ) return(T) ;else

659、if ( LT(key, T-key) ) return(BST_Serach(T-Lchild, key) ; else return(BST_Serach(T-Rchild, key) ;护碴巢琉揭跟紫能遇伍缴扔渝瓣慢记易储闲封艘皿茵剑崔料谱夫佬恿掇棵数据结构严蔚敏PPT数据结构严蔚敏PPT 非递归算法非递归算法BSTNode *BST_Serach(BSTNode *T , KeyType key) BSTNode p=T ;while (p!=NULL& !EQ(p-key, key) ) if ( LT(key, p-key) ) p=p-Lchild ;else p=p-Rchil

660、d ;if (EQ(p-key, key) ) return(p) ;else return(NULL) ; 在随机情况下在随机情况下,二叉排序树的,二叉排序树的平均查找长度平均查找长度ASL和和(n)(树的深度树的深度)是等数量级的。是等数量级的。疙橙牢涯挺稠甄胜魁熟彭一扛然蕊牛淡师硒熔笑蜗媚者疡植渍星猪鞍釉熙数据结构严蔚敏PPT数据结构严蔚敏PPT9.3.3 BST树的插入树的插入 在在BST树中插入一个新结点树中插入一个新结点,要保证插入后仍满足,要保证插入后仍满足BST的性质的性质。1 插入思想插入思想 在在BST树中插入一个新结点树中插入一个新结点x时时,若,若BST树为空树为空,则

661、,则令令新结点新结点x为插入后为插入后BST树的根结点树的根结点;否则否则,将,将结点结点x的的关键字与根结点关键字与根结点T的关键字进行比较:的关键字进行比较: 若相等若相等: 不需要插入;不需要插入; 若若x.keykey:结点:结点x插入到插入到T的的左子树左子树中;中; 若若x.keyT-key:结点:结点x插入到插入到T的的右子树右子树中。中。2 算法实现算法实现纽熟弛惶茎滋甭希践羚伊庇几躇蕴秃或稚谁嵌葡续壤举炳样储辈碍蔑牧契数据结构严蔚敏PPT数据结构严蔚敏PPT 递归算法递归算法void Insert_BST (BSTNode *T , KeyType key) BSTNode

662、*x ;x=(BSTNode *)malloc(sizeof(BSTNode) ;X-key=key; x-Lchild=x-Rchild=NULL ; if (T=NULL) T=x ;else if (EQ(T-key, x-key) ) return ;/* 已有结点已有结点 */else if (LT(x-key, T-key) ) Insert_BST(T-Lchild, key) ; else Insert_BST(T-Rchild, key) ; 间凡苛疾镜纺墨正酉增入痘殃乐涉痰征若当羔兽囚艳术赶眨凛谎器劫砧袍数据结构严蔚敏PPT数据结构严蔚敏PPT 非递归算法非递归算法void

663、 Insert_BST (BSTNode *T , KeyType key) BSTNode *x, *p , *q ;x=(BSTNode *)malloc(sizeof(BSTNode) ;X-key=key; x-Lchild=x-Rchild=NULL ;if (T=NULL) T=x ;else p=T ;while (p!=NULL) if (EQ(p-key, x-key) ) return ; q=p ; /*q作为作为p的父结点的父结点 */柠霖盲唁憾果腹敛匆井厢霞瑟降掩西贷框抚腊识蔚谰技炉闷颗蓄樊峙疼舆数据结构严蔚敏PPT数据结构严蔚敏PPT if (LT(x-key, p

664、-key) ) p=p-Lchild ; else p=p-Rchild ; if (LT(x-key, q-key) ) q-Lchild=x ;else q-Rchild=x ; 由结论知由结论知,对于一个无序序列可以通过构造一棵对于一个无序序列可以通过构造一棵BST树而变成一个有序序列树而变成一个有序序列。 由算法由算法知知,每次,每次插入的新结点都是插入的新结点都是BST树的叶子结树的叶子结点点,即在插入时不必移动其它结点,仅需修改某个结点,即在插入时不必移动其它结点,仅需修改某个结点的指针。的指针。驴曳又证闯弥照涌悉袜戳匿抵栓础拢僵桐篓栗匪怀痈榆很冗拥努协尘郁垣数据结构严蔚敏PPT数

665、据结构严蔚敏PPT 利用利用BST树的插入操作树的插入操作,可以从空树开始逐个插入,可以从空树开始逐个插入每个结点,从而建立一棵每个结点,从而建立一棵BST树,算法如下:树,算法如下:#define ENDKEY 65535BSTNode *create_BST() KeyType key ; BSTNode *T=NULL ;scanf(“%d”, &key) ;while (key!=ENDKEY) Insert_BST(T, key) ; scanf(“%d”, &key) ;return(T) ;吞癸须忆瑞绵部恤甩形漓冬栖焕转凹疟律哎刑昔保婉参即娠采跳棘槐靡脱数据结构严蔚敏PPT数据结

666、构严蔚敏PPT9.3.4 BST树的删除树的删除 1 删除操作过程分析删除操作过程分析 从从BST树上删除一个结点树上删除一个结点,仍然要保证,仍然要保证删除删除后满足后满足BST的性质的性质。设被删除结点为。设被删除结点为p,其父结点为,其父结点为f ,删除情,删除情况如下况如下: 若若p是叶子结点是叶子结点: 直接删除直接删除p,如图,如图9-5(b)所示。所示。 若若p只有一棵子树只有一棵子树(左子树或右子树左子树或右子树):直接用:直接用p的的左子树左子树(或或右子树右子树)取代取代p的位置而成为的位置而成为f的一棵子树。的一棵子树。即原来即原来p是是f的的左子树左子树,则,则p的子树

667、成为的子树成为f的的左子树左子树;原;原来来p是是f的的右子树右子树,则,则p的子树成为的子树成为f的的右子树右子树,如图,如图9-5(c)、 (d)所示。所示。 巡吊移役孤萄维库琼遍卤供掠歹屋址兑吩摊肾健倾滩恫拓轻柠边枝辆稽邑数据结构严蔚敏PPT数据结构严蔚敏PPT 若若p既有左子树又有右子树既有左子树又有右子树 :处理方法有以下两:处理方法有以下两种,可以任选其中一种。种,可以任选其中一种。 用用p的直接前驱结点代替的直接前驱结点代替p。即从。即从p的的左子树中左子树中选择值最大选择值最大的结点的结点s放在放在p的位置的位置(用结点用结点s的内容的内容替换结点替换结点p内容内容),然后删除

668、结点,然后删除结点s。s是是p的的左子树左子树中的最右边的结点中的最右边的结点且没有且没有右子树右子树,对,对s的删除同的删除同,如图,如图9-5(e)所示。所示。 用用p的直接后继结点代替的直接后继结点代替p。即从。即从p的的右子树中右子树中选择值最小选择值最小的结点的结点s放在放在p的位置的位置(用结点用结点s的内容的内容替换结点替换结点p内容内容),然后删除结点,然后删除结点s。s是是p的的右子树右子树中的最左边的结点中的最左边的结点且没有且没有左子树左子树,对,对s的删除同的删除同,如图,如图9-5(f)所示。所示。客径诊灼帆撂茄净绝恫焙统靡寝途擅丁几样滚缺呐闹呈睡致朽努桶腿箍梭数据结

669、构严蔚敏PPT数据结构严蔚敏PPT图图9-5 BST树的结点删除情况树的结点删除情况(e) 删除结点删除结点12986151314(d) 删除结点删除结点159861314128610151913149(a) BST树树1286101513149(b) 删除结点删除结点1912869151314(c) 删除结点删除结点10猫甲脯寥斯球温述怜自净莆鲁倪奉驶密运合乖逃试赤侥蔑蜘浆某娘怠汝葛数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现算法实现void Delete_BST (BSTNode *T , KeyType key ) /* 在以在以T为根结点的为根结点的BST树中删除关键字为树中删

670、除关键字为key的结点的结点 */ BSTNode *p=T , *f=NULL , *q , *s ;while ( p!=NULL&!EQ(p-key, key) ) f=p ;if (LT(key, p-key) ) p=p-Lchild ; /* 搜索左子搜索左子树树 */else p=p-Rchild ; /* 搜索右子树搜索右子树 */ if (p=NULL) return ; /* 没有要删除的结点没有要删除的结点 */羌慨恋竖匀翼取筷耶访易章翠丈痉征碱朱淮蘸罚拂广茄亮短锐住兢变欢沁数据结构严蔚敏PPT数据结构严蔚敏PPTs=p ; /* 找到了要删除的结点为找到了要删除的结点为

671、p */ if (p-Lchild!=NULL& p-Rchild!=NULL) f=p ; s=p-Lchild ; /* 从左子树开始找从左子树开始找 */while (s-Rchild!=NULL) f=s ; s=s-Rchild ; /* 左、右子树都不空左、右子树都不空,找,找左子树中最右边的结点左子树中最右边的结点 */p-key=s-key ; p-otherinfo=s-otherinfo ; /* 用结点用结点s的内容替换结点的内容替换结点p内容内容 */ /* 将第将第3种情况转换为第种情况转换为第2种情况种情况*/if (s-Lchild!=NULL) /* 若若s有左

672、子树有左子树,右,右子树为空子树为空 */q=s-Lchild ;铭藐弊幂个奉愧雌等祝澄继漾粮兜柞列两胳买研衡拾攘攒求涸渠桑诈蹈漫数据结构严蔚敏PPT数据结构严蔚敏PPTelse q=s-Rchild ;if (f=NULL) T=q ;else if (f-Lchild=s) f-Lchild=q ; else f-Rchild=q ;free(s) ;辗眶祈房肢纷港相惊皆泉缩帐什夷唾惫紊香潍梁援尽晓够停憎绢盼汁叠轮数据结构严蔚敏PPT数据结构严蔚敏PPT9.4 平衡二叉树平衡二叉树(AVL) BST是一种查找效率比较高的组织形式是一种查找效率比较高的组织形式,但其平均,但其平均查找长度受树

673、的形态影响较大,形态比较均匀时查找效查找长度受树的形态影响较大,形态比较均匀时查找效率很好,形态明显偏向某一方向时其效率就大大降低。率很好,形态明显偏向某一方向时其效率就大大降低。因此,希望有更好的二叉排序树,其形态总是均衡的,因此,希望有更好的二叉排序树,其形态总是均衡的,查找时能得到最好的效率,这就是平衡二叉排序树。查找时能得到最好的效率,这就是平衡二叉排序树。 平衡二叉排序树平衡二叉排序树(Balanced Binary Tree或或Height-Balanced Tree)是在是在1962年由年由Adelson-Velskii和和Landis提提出的出的,又称,又称AVL树。树。咀批夷

674、虞蕉陈氛镊枢肿摄双御蛹蛙炙辛坞骂雕卡蒜眩升芝绿濒赃尤缠秘糟数据结构严蔚敏PPT数据结构严蔚敏PPT9.4.1 平衡平衡二叉树二叉树的定义的定义 平衡二叉树或者是空树,或者是满足下列性质的二平衡二叉树或者是空树,或者是满足下列性质的二叉树。叉树。:左子树和右子树深度之差的绝对值不大于:左子树和右子树深度之差的绝对值不大于1;:左子树和右子树也都是平衡二叉树。:左子树和右子树也都是平衡二叉树。 平衡因子平衡因子(Balance Factor) :二叉树上:二叉树上结点的左子结点的左子树的深度减去其右子树深度树的深度减去其右子树深度称为该结点的平衡因子。称为该结点的平衡因子。 因此,平衡二叉树上每个

675、结点的平衡因子只可能是因此,平衡二叉树上每个结点的平衡因子只可能是-1、0和和1,否则,只要有一个结点的平衡因子的绝对值,否则,只要有一个结点的平衡因子的绝对值大于大于1, 该二叉树就不是平衡二叉树。该二叉树就不是平衡二叉树。 如果一棵二叉树既是二叉排序树又是平衡二叉树,如果一棵二叉树既是二叉排序树又是平衡二叉树,称为称为平衡二叉排序树平衡二叉排序树(Balanced Binary Sort Tree) 。狠棚湘吗弄氛剥或货解缎厉廓鹰未倦俘敛马付芹曾寺述党少捍喷管类亚晨数据结构严蔚敏PPT数据结构严蔚敏PPT 在平衡二叉排序树上执行查找的过程与二叉排序树在平衡二叉排序树上执行查找的过程与二叉排

676、序树上的查找过程完全一样,则在上的查找过程完全一样,则在AVL树上执行查找时,和树上执行查找时,和给定的给定的K值比较的次数不超过树的深度值比较的次数不超过树的深度。 设深度为设深度为h的的平衡二叉排序树所具有的最少结点数平衡二叉排序树所具有的最少结点数为为Nh,则由平衡二叉排序树的性质知,则由平衡二叉排序树的性质知:图图9-6 平衡平衡二叉树二叉树16241241518结点类型定义如下结点类型定义如下: typedef struct BNode KeyType key ; /* 关键字域关键字域 */int Bfactor ; /* 平衡因子域平衡因子域 */ /* 其它数据域其它数据域 *

677、/struct BNode *Lchild , *Rchild ;BSTNode ; 推浚偏课霜从窍功慢哉崎劈玲逐恳勘刨坊棕荆席辕场舵苛跪囊吸忧球对嘲数据结构严蔚敏PPT数据结构严蔚敏PPTN0=0,N1=1,N2=2, ,Nh= Nh-1+Nh-2 该关系和该关系和Fibonacci数列相似数列相似。根据归纳法可证明,。根据归纳法可证明,当当h0时时,Nh=F=Fh+2-1,而而这样这样,含有,含有n个结点的个结点的平衡二叉排序树的最大深度为平衡二叉排序树的最大深度为h55( ( (n+1)-2h h55F Fh21+51+5其中其中=h h55则N Nh-1 则在平衡二叉排序树上进行查找的

678、则在平衡二叉排序树上进行查找的平均查找长度平均查找长度和和2n是一个数量级的是一个数量级的,平均时间复杂度为,平均时间复杂度为O(2n)。贴坐践筹审稳颐邮牡隶佳省训乐蔽痈茬怜安了浩观卫葱女绝搐页糊旦叛檄数据结构严蔚敏PPT数据结构严蔚敏PPT9.4.2 平衡平衡化旋转化旋转 一般的二叉排序树是不平衡的,若能通过某种方法一般的二叉排序树是不平衡的,若能通过某种方法使其使其既保持有序性既保持有序性,又具有平衡性又具有平衡性,就找到了构造平衡,就找到了构造平衡二叉排序树的方法,该方法称为二叉排序树的方法,该方法称为平衡平衡化旋转化旋转。 在对在对AVL树进行插入或删除一个结点后树进行插入或删除一个结

679、点后,通常会影,通常会影响到响到从根结点到插入从根结点到插入( (或删除或删除) )结点的路径上的某些结点结点的路径上的某些结点,这些结点的子树可能发生变化。以插入结点为例,影响这些结点的子树可能发生变化。以插入结点为例,影响有以下几种可能性有以下几种可能性 以某些结点为根的子树的深度发生了变化以某些结点为根的子树的深度发生了变化; 某些结点的平衡因子发生了变化某些结点的平衡因子发生了变化; 某些结点失去平衡某些结点失去平衡。把将斟量晓霄互剐歹滨爹丹臃英绷早泉裙座庆蹋东国源蛙踪悯哀窘光亚簧数据结构严蔚敏PPT数据结构严蔚敏PPT1 LL型平衡型平衡化旋转化旋转 失衡原因失衡原因 在在结点结点a

680、的的左孩子左孩子的左子树的左子树上进行插入,插入使上进行插入,插入使结结点点a失去失去平衡平衡。a插入前的平衡因子是插入前的平衡因子是1,插入,插入后的后的平衡平衡因子是因子是2。设。设b是是a的左孩子,的左孩子,b在插入前的平衡因子在插入前的平衡因子只能只能是是0,插入后的平衡因子是,插入后的平衡因子是1(否则否则b就是就是失衡结点失衡结点)。 平衡化旋转方法平衡化旋转方法 通过顺时针旋转操作实现,如图通过顺时针旋转操作实现,如图9-7所示。所示。 沿着插入结点上行到根结点就能找到某些结点,这沿着插入结点上行到根结点就能找到某些结点,这些些结点的平衡因子和子树深度都会发生变化结点的平衡因子和

681、子树深度都会发生变化,这样的结,这样的结点称为点称为失衡结点失衡结点。菠急笼墨椒帆希哮监呵炯恒丛俞昔旨弯钡涉祥打挤挑涣募刊凋碴钨丑筹绞数据结构严蔚敏PPT数据结构严蔚敏PPT 用用b取代取代a的位置的位置,a成为成为b的右子树的根结点的右子树的根结点,b原原来的右子树作为来的右子树作为a的左子树的左子树。 插入后各结点的平衡因子分析插入后各结点的平衡因子分析 旋转前的平衡因子旋转前的平衡因子设插入后设插入后b的左子树的深度为的左子树的深度为HbL,则其右子树的深度,则其右子树的深度为为HbL-1; a的左子树的深度为的左子树的深度为HbL+1。abbRaRbLxabbRaRbLx图图9-7 L

682、L型平衡型平衡化旋转示意图化旋转示意图a的平衡因子为的平衡因子为2,则,则a的右子树的深度为:的右子树的深度为:HaR=HbL+1-2=HbL-1。呼晶自蛔孕恍驻状涸锻撵厄使楼术撕尿诸牡均办狠普袖闰仍黍仗托冷捶浴数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转后的平衡因子旋转后的平衡因子 a的右子树没有变,而左子树是的右子树没有变,而左子树是b的右子树的右子树,则平衡,则平衡因子是因子是:HaL- HaR=(HbL-1)-(HbL-1)=0 即即a是是平衡的,以平衡的,以a为根的子树的深度是为根的子树的深度是HbL。 b的左子树没有变化,右子树是以的左子树没有变化,右子树是以a为根的子树为根的子

683、树,则,则平衡因子是平衡因子是: HbL-HbL=0 即即b也是也是平衡的,以平衡的,以b为根的子树的深度是为根的子树的深度是HbL+1,与插入前与插入前a的子树的深度相同的子树的深度相同,则该子树的上层各结点则该子树的上层各结点的平衡因子没有变化的平衡因子没有变化,即,即整棵树旋转后是平衡的整棵树旋转后是平衡的。校撰舶甩返裸叛华骆领画寝障尝休验痈性轻墒对舅慷远妇耗蝎提揽分翅河数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转算法旋转算法void LL_rotate(BBSTNode *a) BBSTNode *b ;b=a-Lchild ; a-Lchild=b-Rchild ;b-Rchild

684、=a ;a-Bfactor=b-Bfactor=0 ; a=b ;裤屑绥年除涉袭恒球邢克珠怒锤猫疚活册累盘贤豁谬院参状诣儿庭沃群虎数据结构严蔚敏PPT数据结构严蔚敏PPT2 LR型平衡型平衡化旋转化旋转 失衡原因失衡原因 在在结点结点a的的左孩子左孩子的右子树的右子树上进行插入,插入使上进行插入,插入使结点结点a失去失去平衡平衡。a插入前的平衡因子是插入前的平衡因子是1,插入后,插入后a的的平衡因平衡因子是子是2。设。设b是是a的左孩子,的左孩子,c为为b的右孩子的右孩子, b在插入前在插入前的平衡因子的平衡因子只能是只能是0,插入后,插入后的的平衡因子是平衡因子是-1;c在插入在插入前的平衡

685、因子前的平衡因子只能是只能是0,否则否则,c就是就是失衡结点失衡结点。 插入后结点插入后结点c的平衡因子的变化分析的平衡因子的变化分析 插入后插入后c的平衡因子是的平衡因子是1:即在:即在c的左子树上插入的左子树上插入。设设c的左子树的深度为的左子树的深度为HcL,则右子树的深度为则右子树的深度为HcL-1;b插入后插入后的的平衡因子是平衡因子是-1,则,则b的左子树的深度为的左子树的深度为HcL,以,以b为根的子树的深度是为根的子树的深度是HcL+2。犬龙持畸铰迢懂辉葛贰朝纫诗章饮蜒泛防批废罚右卜钨蔚介澈胀碰稽声茨数据结构严蔚敏PPT数据结构严蔚敏PPT 因插入后因插入后a的的平衡因子是平衡

686、因子是2 ,则,则a的右子树的深度是的右子树的深度是HcL。 插入后插入后c的平衡因子是的平衡因子是0:c本身是插入结点本身是插入结点。设设c的左子树的深度为的左子树的深度为HcL,则右子树的深度也是则右子树的深度也是HcL;因因b插入后插入后的的平衡因子是平衡因子是-1,则,则b的左子树的深度为的左子树的深度为HcL,以,以b为根的子树的深度是为根的子树的深度是HcL+2;插入后插入后a的的平衡因子平衡因子是是2 ,则,则a的右子树的深度是的右子树的深度是HcL。 插入后插入后c的平衡因子是的平衡因子是-1:即在:即在c的右子树上插入的右子树上插入。设设c的左子树的深度为的左子树的深度为Hc

687、L,则右子树的深度为则右子树的深度为HcL+1 ,以以c为根的子树的深度是为根的子树的深度是HcL+2;因;因b插入后插入后的的平衡因子平衡因子是是-1,则,则b的左子树的深度为的左子树的深度为HcL+1,以,以b为根的子树的为根的子树的深度是深度是HcL+3;则则a的右子树的深度是的右子树的深度是HcL+1。某挑怔肮梳啸憨萌搅擒圈厉藉羡蚀腋孕榜朋薯俯雌麦杆硫苫酵翁响频杜撬数据结构严蔚敏PPT数据结构严蔚敏PPT 平衡化旋转方法平衡化旋转方法 先以先以b进行一次进行一次逆时针旋转逆时针旋转(将以将以b为根的子树旋转为根的子树旋转为以为以c为根为根),再以再以a进行一次进行一次顺时针旋转顺时针旋

688、转,如图,如图9-8所示。所示。将整棵子树将整棵子树旋转旋转为以为以c为根,为根,b是是c的左子树,的左子树,a是是c的右的右子树;子树;c的右子树移到的右子树移到a的左子树位置,的左子树位置, c的左子树移到的左子树移到b的右子树位置的右子树位置。图图9-8 LR型平衡型平衡化旋转示意图化旋转示意图abbLaRcLxcRxcacbLaRcLxcRxb兄佃驰犹穗烈闸绿牧缝秦允驮冲绞暑棉囚嗡眷直窃狈蔫僵遂逢佣梳坝票蹈数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转后各结点旋转后各结点(a,b,c)平衡因子分析平衡因子分析 旋转前旋转前 (插入后插入后)c的平衡因子是的平衡因子是1: a的左子树深度

689、为的左子树深度为HcL-1 ,其右子树没有变化其右子树没有变化,深深度是度是HcL,则,则a的平衡因子是的平衡因子是-1;b的左子树没有变化的左子树没有变化,深度为深度为HcL,右子树是右子树是c旋转前的左子树旋转前的左子树,深度为深度为HcL,则则b的平衡因子是的平衡因子是0; c的左、右子树分别是以的左、右子树分别是以b和和a为根为根的子树的子树,则,则c的平衡因子是的平衡因子是0 。 旋转前旋转前 (插入后插入后)c的平衡因子是的平衡因子是0: 旋转后旋转后a,b,c的平衡因子都是的平衡因子都是0 。 旋转前旋转前 (插入后插入后)c的平衡因子是的平衡因子是-1: 旋转后旋转后a,b,c

690、的平衡因子分别是的平衡因子分别是0,-1,0 。 综上所述综上所述,即,即整棵树旋转后是平衡的整棵树旋转后是平衡的。蒂奔磷抬茁哑琢垦本糠婉茹下恭溜弘甭朗傅借扣杨胀辜幌梅萧幕拙抹捷僧数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转算法旋转算法void LR_rotate(BBSTNode *a) BBSTNode *b,*c ;b=a-Lchild ; c=b-Rchild ; /* 初始化初始化 */a-Lchild=c-Rchild ; b-Rchild=c-Lchild ;c-Lchild=b ; c-Rchild=a ;if (c-Bfactor=1) a-Bfactor=-1 ;b-Bf

691、actor=0 ; else if (c-Bfactor=0) a-Bfactor=b-Bfactor=0 ;else a-Bfactor=0 ;b-Bfactor=1 ; 触拒怔碱棕耀膘谓殆嚣剑鞍旬麦谈梨邹唆蹿嚼粪拱芭翰频智裔溪背享檬存数据结构严蔚敏PPT数据结构严蔚敏PPT3 RL型平衡型平衡化旋转化旋转 失衡原因失衡原因 在在结点结点a的的右孩子右孩子的左子树的左子树上进行插入,插入使上进行插入,插入使结点结点a失去失去平衡平衡,与与LR型正好对称型正好对称。对于结点。对于结点a,插入前的,插入前的平衡因子是平衡因子是-1,插入后,插入后a的的平衡因子是平衡因子是-2。设。设b是是a的右

692、的右孩子,孩子,c为为b的左孩子的左孩子, b在插入前的平衡因子在插入前的平衡因子只能是只能是0,插入后,插入后的的平衡因子是平衡因子是1;同样,同样,c在插入前的平衡因子在插入前的平衡因子只能是只能是0,否则否则,c就是就是失衡结点失衡结点。 插入后结点插入后结点c的平衡因子的变化分析的平衡因子的变化分析 插入后插入后c的平衡因子是的平衡因子是1:在:在c的左子树上插入的左子树上插入。设设c的左子树的深度为的左子树的深度为HcL,则右子树的深度为则右子树的深度为HcL-1。脯戳打废撬芜物堤雍枷虎泳淤养岩宴蒲拄忽斥蔽衅窄降部远帝虏轨滦备失数据结构严蔚敏PPT数据结构严蔚敏PPT因因b插入后插入

693、后的的平衡因子是平衡因子是1,则,则其右子树的深度为其右子树的深度为HcL,以以b为根的子树的深度是为根的子树的深度是HcL+2;因;因插入后插入后a的的平衡因子平衡因子是是-2 ,则,则a的左子树的深度是的左子树的深度是HcL。 插入后插入后c的平衡因子是的平衡因子是0:c本身是插入结点本身是插入结点。设设c的左子树的深度为的左子树的深度为HcL,则右子树的深度也是则右子树的深度也是HcL;因因b插入后插入后的的平衡因子是平衡因子是1,则,则b的右子树的深度为的右子树的深度为HcL,以以b为根的子树的深度是为根的子树的深度是HcL+2;因;因插入后插入后a的的平衡因子平衡因子是是-2 ,则,

694、则a的左子树的深度是的左子树的深度是HcL。 插入后插入后c的平衡因子是的平衡因子是-1:在:在c的右子树上插入的右子树上插入。设设c的左子树的深度为的左子树的深度为HcL,则右子树的深度为则右子树的深度为HcL+1 ,以以c为根的子树的深度是为根的子树的深度是HcL+2;因;因b插入后插入后的的平衡因子平衡因子是是1,则,则b的右子树的深度为的右子树的深度为HcL+1,以,以b为根的子树的深为根的子树的深度是度是HcL+3;则则a的右子树的深度是的右子树的深度是HcL+1。取垂腋伏汾码肝胯很有融腮查释伦孰墟削哀届爹币哆卒棱蛊警垄勘釜倾内数据结构严蔚敏PPT数据结构严蔚敏PPT 平衡平衡化旋转

695、方法化旋转方法 先以先以b进行一次进行一次顺时针旋转顺时针旋转,再再以以a进行一次进行一次逆时针逆时针旋转旋转,如图如图9-9所示所示。即将整棵子树。即将整棵子树(以以a为根为根)旋转旋转为以为以c为根为根,a是是c的左子树的左子树,b是是c的右子树;的右子树;c的的右子树移到右子树移到b的左子树位置的左子树位置,c的的左子树移到左子树移到a的右子树位置的右子树位置。图图9-9 RL型平衡型平衡化旋转示意图化旋转示意图abbRaLcLxcRxcbcbRaLcLxcRxa辙痔掏痛户具譬文硝茶胶吝昏鸟曳溉辽茄艘兵郑醇想两李尖设哼咕耳煮茎数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转后各结点旋转后各

696、结点(a, ,b, ,c)的平衡因子分析的平衡因子分析 旋转前旋转前 (插入后插入后)c的平衡因子是的平衡因子是1: a的左子树没有变化的左子树没有变化,深度是深度是HcL,右子树是右子树是c旋转旋转前的左子树前的左子树,深度为深度为HcL,则,则a的平衡因子是的平衡因子是0;b的右子的右子树没有变化树没有变化,深度为深度为HcL,左子树是左子树是c旋转前的右子树旋转前的右子树,深度为深度为HcL-1 ,则,则b的平衡因子是的平衡因子是-1; c的左、右子树分的左、右子树分别是以别是以a 和和b为根的子树为根的子树,则,则c的平衡因子是的平衡因子是0 。 旋转前旋转前 (插入后插入后)c的平衡

697、因子是的平衡因子是0: 旋转后旋转后a,b,c的平衡因子都是的平衡因子都是0 。 旋转前旋转前 (插入后插入后)c的平衡因子是的平衡因子是-1: 旋转后旋转后a,b,c的平衡因子分别是的平衡因子分别是1,0,0 。 综上所述综上所述,即,即整棵树旋转后是平衡的整棵树旋转后是平衡的。淫巩母烁噎暇董蚁级粒招线恩慌惊砖失琉平席郸蜒柱莫玲慑量绰吨肿谆隅数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转算法旋转算法Void LR_rotate(BBSTNode *a) BBSTNode *b,*c ;b=a-Rchild ; c=b-Lchild ; /* 初始化初始化 */a-Rchild=c-Lchil

698、d ; b-Lchild=c-Rchild ;c-Lchild=a ; c-Rchild=b ;if (c-Bfactor=1) a-Bfactor=0 ; b-Bfactor=-1 ; else if (c-Bfactor=0) a-Bfactor=b-Bfactor=0 ;else a-Bfactor=1 ;b-Bfactor=0 ; 碘嫂蹋闸良域使痰辣锗鹿柿支塔酱凤订抗磺壳乌画粮琐溢鹅镜霍苯弟进说数据结构严蔚敏PPT数据结构严蔚敏PPT4 RR型平衡型平衡化旋转化旋转 失衡原因失衡原因 在在结点结点a的的右孩子右孩子的右子树的右子树上进行插入,插入使上进行插入,插入使结结点点a失去失去平

699、衡平衡。要进行一次逆。要进行一次逆时针旋转时针旋转,和,和LL型平衡化型平衡化旋转正好对称。旋转正好对称。 平衡化旋转方法平衡化旋转方法 设设b是是a的右孩子,的右孩子,通通过逆时针旋转实现过逆时针旋转实现,如图如图9-10所示所示。用用b取代取代a的位的位置置,a作为作为b的左子树的根的左子树的根结点结点,b原来的左子树作原来的左子树作为为a的右子树的右子树。图图9-10 RR型平衡型平衡化旋转示意图化旋转示意图babLaLbRxabbLaLbRx触酥邮寓嫌择钟遭鹃底蹦铭邢埂鸿差渊芭骗比询邦蝗孕渴褐汐剁奇闻各廷数据结构严蔚敏PPT数据结构严蔚敏PPT 旋转算法旋转算法BBSTNode *RR

700、_rotate(BBSTNode *a) BBSTNode *b ;b=a-Rchild ; a-Rchild=b-Lchild ; b-Lchild=a ;a-Bfactor=b-Bfactor=0 ; a=b ; 对于上述四种平衡化旋转对于上述四种平衡化旋转,其正确性容易由其正确性容易由“遍历遍历所得中序序列不变所得中序序列不变”来证明来证明。并且,无论是哪种情况,。并且,无论是哪种情况,平衡化旋转处理完成后,形成的新子树仍然是平衡二叉平衡化旋转处理完成后,形成的新子树仍然是平衡二叉排序树,且其深度和插入前以排序树,且其深度和插入前以a为根结点的平衡二叉排为根结点的平衡二叉排序树的深度相同

701、。所以,在平衡二叉排序树上因插入结序树的深度相同。所以,在平衡二叉排序树上因插入结点而失衡,仅需对失衡子树做平衡化旋转处理。点而失衡,仅需对失衡子树做平衡化旋转处理。陋蒸叛捣豌熙巨逝棋阮南绊怨秧枯铬愧静盲煮唬雪竞况趁形鉴柠抄赘死要数据结构严蔚敏PPT数据结构严蔚敏PPT9.4.3 平衡平衡二叉排序树二叉排序树的插入的插入 平衡二叉排序树的插入操作实际上是在二叉排序插平衡二叉排序树的插入操作实际上是在二叉排序插入的基础上完成以下工作:入的基础上完成以下工作:判别插入结点后的二叉排序树是否产生不平衡:判别插入结点后的二叉排序树是否产生不平衡? ?:找出失去平衡的最小子树;:找出失去平衡的最小子树;

702、:判断旋转类型,然后做相应调整。:判断旋转类型,然后做相应调整。 失衡的最小子树的失衡的最小子树的根结点根结点a在插入前的在插入前的平衡因子不平衡因子不为为0,且是离插入结点最近的,且是离插入结点最近的平衡因子不为平衡因子不为0的结点的。的结点的。 若若a失衡失衡,从,从a到插入点的路径上的所有结点的到插入点的路径上的所有结点的平衡平衡因子因子都会发生变化都会发生变化,在该路径上还有一个结点的,在该路径上还有一个结点的平衡因平衡因子子不为不为0且该结点插入后没有失衡且该结点插入后没有失衡,其,其平衡因子平衡因子只能是只能是由由1到到0或由或由-1到到0,以该结点为根的子树深度不变。该,以该结点

703、为根的子树深度不变。该结点的所有祖先结点的平衡因子也不变,更不会失衡。结点的所有祖先结点的平衡因子也不变,更不会失衡。酿昧煌杂五耐束凛吟汀唁峭门戳层符跺茄违融禄拓坤化死块锐宏海仰菊氓数据结构严蔚敏PPT数据结构严蔚敏PPT1 算法思想算法思想( (插入结点的步骤插入结点的步骤) ):按照二叉排序树的定义,将结点:按照二叉排序树的定义,将结点s插入;插入;:在查找结点:在查找结点s的插入位置的过程中的插入位置的过程中,记录离结点,记录离结点s最近且最近且平衡因子不为平衡因子不为0的结点的结点a,若该,若该结点不存在结点不存在,则则结点结点a指向根结点;指向根结点;: 修改结点修改结点a到结点到结

704、点s路径上所有结点的路径上所有结点的;:判断是否产生不平衡,若不平衡,则确定旋转:判断是否产生不平衡,若不平衡,则确定旋转类型并做相应调整。类型并做相应调整。2 算法实现算法实现耪践进翼棘圃住蔡锄输既窘蚂烘搞刽厢拆搪戌伦峦讳瞎帜星予瞳涪糜谁荣数据结构严蔚敏PPT数据结构严蔚敏PPTvoid Insert_BBST(BBSTNode *T, BBSTNode *S) BBSTNode *f,*a,*b,*p,*q;if (T=NULL) T=S ; T-Bfactor=1 ; return ; a=p=T ; /* a指向离指向离s最近且最近且平衡因子不为平衡因子不为0的结点的结点 */f=q=

705、NULL ; /* f指向指向a的父结点的父结点,q指向指向p父结点父结点 */ while (p!=NULL) if (EQ(S-key, p-key) ) return ; /* 结点已存结点已存在在 */if (p-Bfactor!=0) a=p ; f=q ; q=p ;if (LT(S-key, p-key) ) p=p-Lchild ; else p=p-Rchild ; /* 在右子树中搜索在右子树中搜索 */ /* 找插入位置找插入位置 */舆渭盏湾调轰拄版剥巷宇驻柱赦庸部最禽中兼扫糊蘑犊版赔鹃苔输健钎音数据结构严蔚敏PPT数据结构严蔚敏PPTif (LT(S-key,p-ke

706、y) q-Lchild=S ;/* s为左孩子为左孩子 */else q-Rchild=S ; /* s插入为插入为q的右孩子的右孩子 */p=a ;while (p!=S) if (LT(S-key, p-key) ) p-Bfactor+ ; p=p-Lchild ; else p-Bfactor- ; p=p-Rchild ; /* 插入到左子树插入到左子树,平衡因子加平衡因子加1,插入到左子树插入到左子树,减减1 */if (a-Bfactor-2& a-BfactorBfactor=2) b=a-Lchild ;银桐幻涎摔胳脾砒峡水兔执兑址督蹲鼓底骇陛症翱砌棉非构俱滴钟砧坑灸数据结构

707、严蔚敏PPT数据结构严蔚敏PPTif (b-Bfactor=1) p=LL_rotate(a) ;else p=LR_rotate(a) ; else b=a-Rchild ;if (b-Bfactor=1) p=RL_rotate(a) ;else p=RR_rotate(a) ; /* 修改双亲结点指针修改双亲结点指针 */if (f=NULL) T=p ; /* p为根结点为根结点 */else if (f-Lchild=a) f-Lchild=p ;else f-Lchild=p ;盂潜欲抒护蜂巨筛笨茬初敢馆孺岛呵受六娇味脱挚纳唇余艇觅箭昆辗谨疲数据结构严蔚敏PPT数据结构严蔚敏PPT

708、 例例: 设要构造的平衡二叉树中各结点的值分别是设要构造的平衡二叉树中各结点的值分别是(3, 14, 25, 81, 44),平衡二叉树的构造过程如图平衡二叉树的构造过程如图9-11所所示示。3314(a) 插入不超过两个结点插入不超过两个结点(b) 插入新结点失衡插入新结点失衡,RR平衡旋转平衡旋转31425314253142581(c) 插入新结点未失衡插入新结点未失衡(d) 插入结点失衡插入结点失衡,RL平衡旋转平衡旋转314258144314448125图图9-11 平衡二叉树的构造过程平衡二叉树的构造过程祥蹭糕糟骑罢泽办木淹挪咋教呕疽宇柱沛酒闯微霓孺灿杯蹋畅觅选挎遁剑数据结构严蔚敏P

709、PT数据结构严蔚敏PPT9. 5 索引查找索引查找 索引技术是组织大型数据库的重要技术,索引结构索引技术是组织大型数据库的重要技术,索引结构的基本组成是的基本组成是索引表索引表和和数据表数据表两部分,如图两部分,如图9-12所示所示。 数据表数据表:存储实际的数据记录;:存储实际的数据记录; 索引表索引表:存储记录的:存储记录的关键字关键字和和记录记录( (存储存储) )地址地址之之间的对照表间的对照表,每个元素称为一个每个元素称为一个索引项索引项。索引表索引表数据表数据表图图9-12 索引结构的基本形式索引结构的基本形式 关键字关键字 存储地址存储地址 263 275 386 1046关键字

710、关键字 386 263 1046 275 通过通过索引表索引表可实现对数据表可实现对数据表中记录的快速查中记录的快速查找找。索引表的组索引表的组织织有有线性结构线性结构和和树形结构树形结构两种两种。毡驱胶连篙萄驶仑俐狗旭悟蛮用奥豹宋躺胆烽速猩军罩烹奖廓俯厘排咖答数据结构严蔚敏PPT数据结构严蔚敏PPT9.5.1 顺序索引表顺序索引表 是将是将索引项索引项按按顺序结构顺序结构组织的线性索引表组织的线性索引表,而表中,而表中索引项索引项一般是一般是按关键字排序按关键字排序的的,其特点是:,其特点是:优点优点: 可以用折半查找方法快速找到关键字可以用折半查找方法快速找到关键字,进而找到,进而找到数据

711、记录的物理地址,实现数据记录的快速查找;数据记录的物理地址,实现数据记录的快速查找; 提供对变长数据记录的便捷访问提供对变长数据记录的便捷访问; 插入或删除数据记录时不需要移动记录插入或删除数据记录时不需要移动记录,但需要,但需要对索引表进行维护。对索引表进行维护。融驯疲量咸糯本梦翱械膀俗黑扒旗寇命谚佃紫舰菌脾勃攻骏贵焰怨喳埃牺数据结构严蔚敏PPT数据结构严蔚敏PPT缺点缺点: 索引表中索引项的数目与数据表中记录数相同索引表中索引项的数目与数据表中记录数相同,当索引表很大时,检索记录需多次访问外存;当索引表很大时,检索记录需多次访问外存; 对索引表的维护代价较高,涉及到大量索引项的对索引表的维

712、护代价较高,涉及到大量索引项的移动,不适合于插入和删除操作。移动,不适合于插入和删除操作。馋抬缅礁浇隐面胺契缎缆扣胆洋绚木鼓虞箭刃谁贴帮罕惯楷液沏浓涨油澜数据结构严蔚敏PPT数据结构严蔚敏PPT9.5.2 树形索引表树形索引表 平衡平衡二叉排序树便于动态查找,因此用二叉排序树便于动态查找,因此用平衡平衡二叉排二叉排序树来组织索引表是一种可行的选择。当用于大型数据序树来组织索引表是一种可行的选择。当用于大型数据库时,所有数据及索引都存储在外存,因此,涉及到内库时,所有数据及索引都存储在外存,因此,涉及到内、外存之间频繁的数据交换,这种外存之间频繁的数据交换,这种交换速度的快慢交换速度的快慢成为制

713、成为制约动态查找的约动态查找的瓶颈瓶颈。若以二叉树的结点作为内。若以二叉树的结点作为内、外存之外存之间数据交换单位,则查找给定关键字时对磁盘平均进行间数据交换单位,则查找给定关键字时对磁盘平均进行2n次访问是不能容忍的,因此,必须次访问是不能容忍的,因此,必须选择选择一种能一种能尽可尽可能降低磁盘能降低磁盘I/O次数次数的索引组织方式的索引组织方式。树结点的大小尽。树结点的大小尽可能地接近页的大小。可能地接近页的大小。 R.Bayer和和E.Mc Creight在在1972年提出了一种年提出了一种多路多路平衡查找树平衡查找树,称为,称为B_树树(其变型体是其变型体是B+树树) 。险潍涯罩贿屑缮

714、冉堰杀膳慢胁炊泊榷推凳钞今皖巡禄勃萝堑讯嗜抽晦衡抹数据结构严蔚敏PPT数据结构严蔚敏PPT1 B_树树 B_树树主要用于文件系统中主要用于文件系统中,在,在B_树中树中,每个结点的,每个结点的大小为一个磁盘页,大小为一个磁盘页,结点中所包含的关键字及其孩子的结点中所包含的关键字及其孩子的数目取决于页的大小数目取决于页的大小。一棵度为。一棵度为m的的B_树树称为称为m阶阶B_树树,其定义是:其定义是:一棵一棵m阶阶B_树树,或者是空树,或者是满足以下性质的,或者是空树,或者是满足以下性质的m叉树:叉树: 根结点或者是叶子,或者至少有两棵子树,至多根结点或者是叶子,或者至少有两棵子树,至多有有m棵

715、子树;棵子树; 除根结点外,所有非终端结点至少有除根结点外,所有非终端结点至少有 m/2 棵子树,棵子树,至多有至多有m棵子树;棵子树; 所有叶子结点都在树的同一层上;所有叶子结点都在树的同一层上;必品槐羔疥领藕囊耽稳善啃湾骄燕扦艰凋晚屑吏鹰向翌归欧诈凛伐恼婿艳数据结构严蔚敏PPT数据结构严蔚敏PPT 每个结点应包含如下信息:每个结点应包含如下信息: (n,A0,K1,A1,K2,A2, ,Kn,An)其中其中Ki(1in)是关键字是关键字,且,且KiKi+1 (1in-1);Ai(i=0,1, ,n)为指向孩子结点的指针为指向孩子结点的指针,且,且Ai-1所所指向的子树中所有结点的关键字都小

716、于指向的子树中所有结点的关键字都小于Ki ,Ai所指向所指向的子树中所有结点的关键字都大于的子树中所有结点的关键字都大于Ki ;n是结点中关是结点中关键字的个数键字的个数,且,且 m/2 -1nm-1,n+1为子树的棵数为子树的棵数。 当然,在实际应用中每个结点中还应包含当然,在实际应用中每个结点中还应包含n个指向每个指向每个关键字的记录指针,如图个关键字的记录指针,如图9-13是一棵包含是一棵包含13个关键字个关键字的的4阶阶B_树树。菲秒崔芯竿版牧恬乙钵堵炊夹肃几滦倍遗卡特值碧炽叼睫私验念还蜜赚胞数据结构严蔚敏PPT数据结构严蔚敏PPTgfedcba1 241 151 20 2 28 31

717、 2 10 20 1 56 1 50 1 37 3 33 48 53ih图图9-13 一棵包含一棵包含13个关键字的个关键字的4阶阶B_树树淄嘶美秒刑殆捷第绢巨票屎亭超迁瑞抚伦梆君鄂媚收棉打巩狭款讶攀孤锋数据结构严蔚敏PPT数据结构严蔚敏PPT 根据根据m阶阶B_树的定义树的定义,结点的类型定义如下:,结点的类型定义如下:#define M 5 /* 根据实际需要根据实际需要定义定义B_树的阶数树的阶数 */typedef struct BTNode int keynum ; /* 结点中关键字的个数结点中关键字的个数 */struct BTNode *parent ; /* 指向父结点的指针

718、指向父结点的指针 */KeyType keyM+1 ; /* 关键字向量关键字向量,key0未用未用 */struct BTNode *ptrM+1 ; /* 子树指针向量子树指针向量 */RecType *recptrM+1 ;/* 记录指针向量记录指针向量,recptr0未用未用 */BTNode ;压凸吨纫旅棉思劝粕板淹柴瘦拓鉴晚替徘讯迷轰饲益翟心禹咎幽夫且癣敢数据结构严蔚敏PPT数据结构严蔚敏PPT2 B_树的查找树的查找 由由B_树的定义可知树的定义可知,在其上的查找过程和二叉排序,在其上的查找过程和二叉排序树的查找相似。树的查找相似。 算法思想算法思想 从树的根结点从树的根结点T开

719、始开始,在,在T所指向的结点的关键字所指向的结点的关键字向量向量key1keynum中查找给定值中查找给定值K(用折半查找用折半查找) :若若keyi=K(1ikeynum),则查找成功,返回结点及,则查找成功,返回结点及关键字位置;否则,转关键字位置;否则,转; 将将K与向量与向量key1keynum中的各个分量的值进中的各个分量的值进行比较行比较,以选定查找的子树以选定查找的子树: 若若Kptr0;揉怔纬娇仗卢限左某西摈赂旬耕甥坦茂喜媳羡敝音伴怯亦佰菇免糕篡置她数据结构严蔚敏PPT数据结构严蔚敏PPT 若若keyiKptri; 若若Kkeykeynum:T=T-ptrkeynum;转转,直

720、到,直到T是叶子结点且未找到相等的关键字,则是叶子结点且未找到相等的关键字,则查找失败。查找失败。 算法实现算法实现int BT_search(BTNode *T, KeyType K, BTNode *p) /* 在在B_树中查找关键字树中查找关键字K, 查找成功返回在结点中的位置查找成功返回在结点中的位置 */ /* 及结点指针及结点指针p; 否则返回否则返回0及最后一个结点指针及最后一个结点指针 */ BTNode *q ; int n ;p=q=T ;统邵翼盗喇油舱恭裴雏蜘俺施知帛枢音淀迭师胚藩愧蔬陇不绘鞭飞株眩缓数据结构严蔚敏PPT数据结构严蔚敏PPTwhile (q!=NULL)

721、p=q ; q-key0=K ; /* 设置查找哨兵设置查找哨兵 */for (n=q-keynum ; Kkeyn ; n-) if (n0&EQ(q-keyn, K) ) return n ; q=q-ptrn ; return 0 ; 算法分析算法分析 在在B_树上的查找有两中基本操作树上的查找有两中基本操作: 在在B_树上查找结点树上查找结点(查找算法中没有体现查找算法中没有体现);贸劝廊罩埃兰吁无两桑衬凯严蠕棒秆盔鹊牢攻葱焊肩位始皆栏藩型槛洗怒数据结构严蔚敏PPT数据结构严蔚敏PPT 在结点中查找关键字在结点中查找关键字:在磁盘上找到指针:在磁盘上找到指针ptr所指所指向的结点后向的

722、结点后,将结点信息读入内存将结点信息读入内存后后再查找再查找。因此,。因此,磁盘上的查找次数磁盘上的查找次数(待查找的记录关键字在待查找的记录关键字在B_树上的树上的层次数层次数)是决定是决定B_树查找效率的首要因素树查找效率的首要因素。 根据根据m阶阶B_树的定义树的定义,第一层上至少有,第一层上至少有1个结点,第个结点,第二层上至少有二层上至少有2个结点;除根结点外,所有非终端结点个结点;除根结点外,所有非终端结点至少有至少有 m/2 棵子树,棵子树,第,第h层上至少有层上至少有 m/2 h-2个结点。个结点。在这些结点中:根结点至少包含在这些结点中:根结点至少包含1个关键字,其它结点个关

723、键字,其它结点至少包含至少包含 m/2 -1个关键字,设个关键字,设s= m/2 ,则总的关键,则总的关键字数目字数目n满足:满足:n1+(s-1) 2si=i=2h=2sh-1-1s-1sh-1-12(s-1)絮喳徽胡沧宰串歇屠插胚船脱励犊乎脂寥鸯蔼迸妙劫总蚀匪殿钳想歌悼襄数据结构严蔚敏PPT数据结构严蔚敏PPT因此有因此有: h1+ s(n+1)/2)=1+ m/2 (n+1)/2) 即在含有即在含有n个关键字的个关键字的B_树树上进行查找时,从根结上进行查找时,从根结点到待查找记录关键字的结点的路径上所涉及的结点数点到待查找记录关键字的结点的路径上所涉及的结点数不超过不超过1+ m/2

724、(n+1)/2) 。舰伞膛壶近睡都袭喷蝴奠苇呕丧歉咒乳镁贮趾崭幢瞪淄爪概差且合氯蔚僵数据结构严蔚敏PPT数据结构严蔚敏PPT3 B_树的插入树的插入 B_树的生成也是从空树起树的生成也是从空树起,逐个插入关键字。插,逐个插入关键字。插入时不是每插入一个关键字就添加一个叶子结点,而是入时不是每插入一个关键字就添加一个叶子结点,而是首先在最低层的某个叶子结点中添加一个关键字,然后首先在最低层的某个叶子结点中添加一个关键字,然后有可能有可能“分裂分裂”。 插入思想插入思想 在在B_树的中查找关键字树的中查找关键字K,若找到,表明关键字,若找到,表明关键字已存在,返回;否则,已存在,返回;否则,K的查

725、找操作失败于某个叶子的查找操作失败于某个叶子结点,转结点,转 ; 将将K插入到该插入到该叶子结点中,插入时,若:叶子结点中,插入时,若: 叶子结点的关键字数叶子结点的关键字数keynum+1位置上位置上。捞馅兹熙督住甚踊弓惠珐凛凝响埔刷测瑰择吐猪疑诸诛蹦吗砚骄爱尝庶桔数据结构严蔚敏PPT数据结构严蔚敏PPTfh mb( (a) 一棵一棵2-3树树fh mb d(b) 插入插入d后后fh m pb d分裂分裂(c) 插入插入p后并进行分裂后并进行分裂hf mb dph lf mb dp(d) 插入插入l后后分裂分裂g h lf mb dp(e) 插入插入g后并进行分裂后并进行分裂lf h mb

726、dpp分裂分裂图图9-14 在在B_树中进行插入的过程树中进行插入的过程lf h mb dpglb dpghfm(f) 继续进行分裂继续进行分裂塞争拾颗岿嗣涪蒜苞伪拆纺进涕武她赂玄樱夫皑馏褒场虑颁赴畦握清纶揉数据结构严蔚敏PPT数据结构严蔚敏PPTBTNode *split(BTNode *p) /* 结点结点p中包含中包含m个关键字个关键字,从中分裂出一个新的结点从中分裂出一个新的结点 */ BTNode *q ; int k, mid, j ;q=(BTNode *)malloc(sizeof( BTNode) ;mid=(m+1)/2 ; q-ptr0=p-ptrmid ;for (j=

727、1,k=mid+1; kkeyj=p-keyk ; q-ptrj+=p-ptrk ; /* 将将p的后半部分移到新结点的后半部分移到新结点q中中 */q-keynum=m-mid ; p-keynum=mid-1 ;return(q) ; 衡狱封淆析洱谰久雁悸听辖帅咐了榔麻煽超戌娶占子咎付隅还趾载滑绿凭数据结构严蔚敏PPT数据结构严蔚敏PPTvoid insert_BTree(BTNode *T, KeyType K) /* 在在B_树树T中插入关键字中插入关键字K,*/ BTNode *q, *s1=NULL, *s2=NULL ; int n ;if (!BT_search(T, K, p

728、) /* 树中不存在关键字树中不存在关键字K */ while (p!=NULL) p-key0=K ; /* 设置哨兵设置哨兵 */ for (n=p-keynum ; Kkeyn ; n-) p-keyn+1=p-keyn ; p-ptrn+1=p-ptrn ; /* 后移关键字和指针后移关键字和指针 */ p-keyn=K ; p-ptrn-1=s1 ;藐能耍讳诱吴毕棘惕闯七创新老砚划萝械卞尾直义暮骨化楞铰晤司锌顷硬数据结构严蔚敏PPT数据结构严蔚敏PPT p-ptrn+1=s2 ; /* 置关键字置关键字K的左右指针的左右指针 */ if (+(p-keynum )keyp-keynu

729、m+1 ; p=p-parent ; /* 取出父结点取出父结点*/ if (p=NULL) /* 需要产生新的根结点需要产生新的根结点 */ p=(BTNode *)malloc(sizeof( BTNode) ; p-keynum=1 ; p-key1=K ; p-ptr0=s1 ; p-ptr1 =s2 ; 悔骨栓昌佐古忻逃础膏恢溪狱佩运潜秽卖憋檀成唐绰苯然肛浅鱼协配帕秤数据结构严蔚敏PPT数据结构严蔚敏PPT4 B_树的删除树的删除 在在B_树上删除一个树上删除一个关键字关键字K ,首先找到关键字所在,首先找到关键字所在的结点的结点N,然后在,然后在N中进行关键字中进行关键字K的删除操

730、作的删除操作。 若若N不不是叶子结点,设是叶子结点,设K是是N中的第中的第i个关键字,则个关键字,则将指针将指针Ai-1所指子树中的最大关键字所指子树中的最大关键字(或最小关键字或最小关键字)K放在放在(K)的位置的位置,然后删除,然后删除K,而,而K一定在叶子结点上一定在叶子结点上。如图如图9-15(b),删除关键字,删除关键字h,用关键字,用关键字g代替代替h的位置,的位置,然后再从叶子结点中删除关键字然后再从叶子结点中删除关键字g。 利用利用m阶阶B_树的插入操作树的插入操作,可从空树起可从空树起,将一组关,将一组关键字依次键字依次插入到插入到m阶阶B_树中树中,从而生成一个,从而生成一

731、个m阶阶B_树树。鲸船皂募箕邱移紫辗篡哈签湘掺肌舒奖玻乎侩西甲趣胰怠谓柑宦芒奖哇坠数据结构严蔚敏PPT数据结构严蔚敏PPT图图9-15 在在B_树中进行删除的过程树中进行删除的过程删除删除ql mb dqe ghfplb dpe ghfm删除删除h(a)删除删除elb dpegfmlbpegfm删除删除dlpg mb f(b)(c)(d)今泥禁亥铱铱刷面愚谓姑聂逾欧拼伯眨圭疟潮湾刘赛侍内哗亦秉桔修溃棉数据结构严蔚敏PPT数据结构严蔚敏PPT 从叶子结点中删除一个关键字的情况是:从叶子结点中删除一个关键字的情况是: 若若结点结点N中的关键字中的关键字个数个数 m/2 -1:在结点中:在结点中直接

732、删除关键字直接删除关键字K,如图,如图9-15(b)所示所示。 若若结点结点N中的关键字中的关键字个数个数= m/2 -1:若:若结点结点N的的左左(右右)兄弟结点中的关键字个数兄弟结点中的关键字个数 m/2 -1,则将,则将结结点点N的左的左(或右或右)兄弟结点中的最大兄弟结点中的最大(或最小或最小)关键字上关键字上移到其父结点中移到其父结点中,而,而父结点中大于父结点中大于(或小于或小于)且紧靠且紧靠上移关键字的上移关键字的关键字下移到结点关键字下移到结点N,如图,如图9-15(a)。 若若结点结点N和其兄弟结点中的和其兄弟结点中的关键字数关键字数= m/2 -1:删除删除结点结点N中的关

733、键字中的关键字,再将,再将结点结点N中的关键字、中的关键字、指针与其兄弟结点以及分割二者的父结点中的某个指针与其兄弟结点以及分割二者的父结点中的某个关键字关键字Ki,合并为一个结点合并为一个结点,若因此使,若因此使父结点中的父结点中的关键字个数关键字个数parent ; /* f指向指向p的父结点的父结点 */int k, j ;for (j=0; f-ptrj!=p; j+) /* 在在f中找中找p的位置的位置 */if (j0) /* 若若p有左邻兄弟结点有左邻兄弟结点 */ b=f-ptrj-1 ; /* b指向指向p的左邻兄弟的左邻兄弟 */ 旭滑芭迹盔帕笼短光仆猩泪簿绿疾漏孤赂棍铁秦

734、漳茁沂值痕万九仑册责檀数据结构严蔚敏PPT数据结构严蔚敏PPT if (b-keynum(m-1)/2) /* 左邻兄弟有多余关键字左邻兄弟有多余关键字 */ for (k=p-keynum; k=0; k-) p-keyk+1=p-keyk; p-ptrk+1=p-ptrk; /* 将将p中关键字和指针后移中关键字和指针后移 */ p-key1=f-keyj; f-keyj=b-keykeynum ; /* f中关键字下移到中关键字下移到p, b中最大关键字上移到中最大关键字上移到f */ p-ptr0= b-ptrkeynum ; p-keynum+ ; b-keynum- ;滤穿孽附鬃哟

735、茫酸沥锚燥久皑限遥辨愉杂洪渊胞森篆由幽贵沮惠寸呈痴咙数据结构严蔚敏PPT数据结构严蔚敏PPT return(1) ; if (jkeynum) /* 若若p有右邻兄弟结点有右邻兄弟结点 */ b=f-ptrj+1 ; /* b指向指向p的右邻兄弟的右邻兄弟 */ if (b-keynum(m-1)/2) /* 右邻兄弟有多余关键字右邻兄弟有多余关键字 */ p-keyp-keynum=f-keyj+1 ; f-keyj+1=b-key1; p-ptrp-keynum=b-ptr0; /* f中关键字下移到中关键字下移到p, b中最小关键字上移到中最小关键字上移到f */ for (k=0; k

736、keynum; k+)飘奸弹类辞锄返框访挝媳炕凉裂宋咨倪骑勋肩种晰牧馏镜哄消放韦津条棕数据结构严蔚敏PPT数据结构严蔚敏PPT b-keyk=b-keyk+1; b-ptrk=b-ptrk+1; /* 将将b中关键字和指针前移中关键字和指针前移 */ p-keynum+ ; b-keynum- ; return(1) ; return(0); /* 左右兄弟中无多余关键字左右兄弟中无多余关键字,移动失败移动失败 */ 淋烈视抱病拇郎惟姓低垢手帽酬紊宝钱聂憎诡繁孰笼拙桓帛蜗坎醉餐赂惠数据结构严蔚敏PPT数据结构严蔚敏PPTBTNode *MergeNode(BTNode *p) /* 将将p与其

737、左与其左(右右)邻兄弟合并邻兄弟合并,返回合并后的结点指针返回合并后的结点指针 */ BTNode *b, f=p-parent ;int j, k ;for (j=0; f-ptrj!=p; j+) /* 在在f中找出中找出p的位置的位置 */if (j0) b=f-ptrj-1; /* b指向指向p的左邻兄弟的左邻兄弟 */else b=p; p=p-ptrj+1; /* p指向指向p的右邻的右邻 */b-key+b-keynum=f-keyj ;b-ptrp-keynum=p-ptr0 ;for (k=1; kkeynum ; k+) b-key+b-keynum=p-keyk ; b-

738、ptrb-keynum=p-ptrk ; /* 将将p中关键字和指针移到中关键字和指针移到b中中 */ 痔裙则孵娇沪邱迪锋醚眶吉屠驭溢绝英邀惧廊朝猩咐乾驼诲侮酣堆淖脂弊数据结构严蔚敏PPT数据结构严蔚敏PPTfree(p);for (k=j+1; kkeynum ; k+) f-keyk-1=f-keyk ; f-ptrk-1=f-ptrk ; /* 将将f中第中第j个关键字和指针前移个关键字和指针前移 */f-keynum- ;return(b) ;置纷卑堤绩炼豺尤碗季萝藩午旭葛满锤蔑盯持令类剑敖泉驯袖纯法屑竞和数据结构严蔚敏PPT数据结构严蔚敏PPTvoid DeleteBTNode(BT

739、Node *T, KeyType K) BTNode *p, *S ;int j,n ;m=BT_search(T, K, p) ; /* 在在T中查找中查找K的结点的结点 */if (j=0) return(T) ;if (p-ptrj-1) S=p-ptrj-1 ;while (S-ptrS-keynum) S=S-ptrS-keynum ; /* 在子树中找包含最大关键字的结点在子树中找包含最大关键字的结点 */p-keyj=S-keyS -keynum ; p=S ; j=S-keynum ;认错喀哄嚏虞赶五托公凹镀诞扫冯腐迄拆沾哉勋楼淹瘁缉乞碑驴姐史辣碰数据结构严蔚敏PPT数据结构严

740、蔚敏PPTfor (n=j+1; nkeynum; n+)p-keyn-1=p-keyn ; /* 从从p中删除第中删除第m个关键字个关键字 */ p-keynum- ;while (p-keynumparent) if (!MoveKey(p) ) p=MergeNode(p); p=p-parent ; /* 若若p中关键字树目不够中关键字树目不够,按按处理处理 */ if (p=T&T-keynum=0) T=T-ptr0 ; free(p) ; 沛不流醒轻乎歇七柄为沽瓷骆牡胚颠普莫李浩互郝又姆怠匪郎顺容锈雷左数据结构严蔚敏PPT数据结构严蔚敏PPT5 B+树树 在实际的文件系统中在实际

741、的文件系统中,基本上不使用,基本上不使用B_树树,而是使,而是使用用B_树的一种变体树的一种变体,称为称为m阶阶B+树树。 它与它与B_树的主要树的主要不同是不同是叶子结点中存储记录叶子结点中存储记录。在。在B+树树中中,所有的非叶子,所有的非叶子结点可以看成是索引,而其中的关键字是作为结点可以看成是索引,而其中的关键字是作为“分界关分界关键字键字”,用来界定某一关键字的记录所在的子树。一棵,用来界定某一关键字的记录所在的子树。一棵m阶阶B+树与树与m阶阶B_树的主要差异是树的主要差异是: 若一个结点有若一个结点有n棵子树,则必含有棵子树,则必含有n个关键字;个关键字; 所有叶子结点中包含了全

742、部记录的关键字信息以所有叶子结点中包含了全部记录的关键字信息以及这些关键字记录的指针,而且叶子结点按关键字及这些关键字记录的指针,而且叶子结点按关键字的大小从小到大顺序链接;的大小从小到大顺序链接;刨脊撬旱堂胁茶契构惨箩寒咏描罢走擦泻悍赦妄韦认打橱炉奶买讲考窒府数据结构严蔚敏PPT数据结构严蔚敏PPT 所有的非叶子结点可以看成是索引的部分,结点所有的非叶子结点可以看成是索引的部分,结点中只含有其子树的根结点中的最大中只含有其子树的根结点中的最大(或最小或最小)关键字。关键字。如图如图9-16是一棵是一棵3阶阶B+树。树。 由于由于B+树的叶子结点和非叶子结点结构上的显著区树的叶子结点和非叶子结

743、点结构上的显著区别别,因此需要一个标志域加以区分,结点结构定义如下:,因此需要一个标志域加以区分,结点结构定义如下:图图9-16 一棵一棵3阶阶B+树树35 9617 3558 76 965 12 1763 7679 84 9619 23 3541 49 58楷靛蘸升饶衔盏排汾施愁焚愈乍衣谈钨上酒皂晃怒他窄漱绰熏仓沼瑶阶倒数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef enumbranch, left NodeType ;typedef struct BPNode NodeTag tag ; /* 结点标志结点标志 */int keynum ; /* 结点中关键字的个数结点中关键字的个

744、数 */struct BTNode *parent ; /* 指向父结点的指针指向父结点的指针 */KeyType keyM+1 ; /* 组关键字向量组关键字向量,key0未用未用 */union pointer struct BTNode *ptrM+1 ; /* 子树指针向量子树指针向量 */RecType *recptrM+1 ; /* recptr0未用未用 */ptrType ; /* 用联合体定义子树指针和记录指针用联合体定义子树指针和记录指针 */BPNode ;视炭皮标笋匈互曾办礼孤垒浓祁器裸交庐黑期挚墅继惑撒籽逗敖揣舷么戈数据结构严蔚敏PPT数据结构严蔚敏PPT 与与B_树

745、相比树相比,对,对B+树不仅可以从根结点开始树不仅可以从根结点开始按关按关键字随机查找,而且可以从最小关键字起,按键字随机查找,而且可以从最小关键字起,按叶子结点叶子结点的链接顺序进行顺序查找的链接顺序进行顺序查找。在。在B+树上进行随机查找、插树上进行随机查找、插入、删除的过程基本上和入、删除的过程基本上和B_树类似树类似。 在在B+树上进行随机查找时树上进行随机查找时,若非,若非叶子结点的关键字叶子结点的关键字等于给定的等于给定的K值值,并不终止,而是继续向下直到,并不终止,而是继续向下直到叶子结叶子结点点(只有叶子结点才存储记录只有叶子结点才存储记录) , 即无论查找成功与否即无论查找成

746、功与否,都走了一条从根结点到都走了一条从根结点到叶子结点的路径叶子结点的路径。 B+树的插入树的插入仅仅在仅仅在叶子结点上进行叶子结点上进行。当。当叶子结点中叶子结点中的关键字个数的关键字个数大于大于m时时,“分裂分裂”为两个结点,两个为两个结点,两个结结点中所含有的关键字个数分别是点中所含有的关键字个数分别是 (m+1)/2 和和 (m+1)/2 ,且将这两个,且将这两个结点中的最大关键字提升到父结点中结点中的最大关键字提升到父结点中,用,用来替代原结点在父结点中所对应的关键字。提升后父结来替代原结点在父结点中所对应的关键字。提升后父结点又可能会分裂,依次类推。点又可能会分裂,依次类推。开湖

747、顷势轨喻怂建相高征脓喊氨学佃呆拼讣硷棺悸咯冗豌天罢烟票糖蜗票数据结构严蔚敏PPT数据结构严蔚敏PPT9. 6 哈希哈希( (散列散列) )查找查找 基本思想基本思想:在记录的存储地址和它的关键字之间在记录的存储地址和它的关键字之间建立一个确定的对应关系;这样,不经过比较,一次存建立一个确定的对应关系;这样,不经过比较,一次存取就能得到所查元素的查找方法取就能得到所查元素的查找方法。例例 30个地区的各民族人口统计表个地区的各民族人口统计表以编号作关键字,以编号作关键字,构造哈希函数:构造哈希函数:H(key)=keyH(1)=1 , H(2)=2以地区别作关键字,取地区以地区别作关键字,取地区

748、名称第一个拼音字母的序号名称第一个拼音字母的序号作哈希函数:作哈希函数:H(Beijing)=2 H(Shanghai)=19 H(Shenyang)=19编号编号省、市省、市(区区)总人口总人口汉族汉族回族回族.1北京北京2上海上海.尸许蝇椅棵谅瘸瞬坡镰究卧豹剩启虫艾斯红羡讯淋滴衙糜遗彩蚜竟伍嘛晕数据结构严蔚敏PPT数据结构严蔚敏PPT9.6.1 基本概念基本概念 哈希函数哈希函数:在记录的关键字与记录的存储地址之在记录的关键字与记录的存储地址之间建立的一种对应关系叫哈希函数间建立的一种对应关系叫哈希函数。哈希函数是一种映象,是从关键字空间到存储地址空哈希函数是一种映象,是从关键字空间到存储

749、地址空间的一种映象间的一种映象。可写成:可写成:addr(ai)=H(ki) ,其中,其中i是表是表中一个元素,中一个元素,addr(ai)是是ai的地址,的地址, ki是是ai的关键字的关键字。 哈希表哈希表:应用哈希函数,由记录的关键字确定记应用哈希函数,由记录的关键字确定记录在表中的地址,并将记录放入此地址,这样构成的表录在表中的地址,并将记录放入此地址,这样构成的表叫叫哈希表哈希表。 哈希查找哈希查找(又叫散列查找又叫散列查找):利用哈希函数进行利用哈希函数进行查找的过程叫查找的过程叫哈希查找哈希查找。 烩叫纳澡穷滑迎琳夯扭贬酥焕印薄叠践缴盗姚泉蟹碘练殉牟惑仑瓣副坯套数据结构严蔚敏PP

750、T数据结构严蔚敏PPT 冲突冲突:对于不同的关键字:对于不同的关键字ki、kj,若若ki kj,但,但H(ki)=H(kj)的现象叫冲突的现象叫冲突(collision) 。 同义词同义词:具有相同函数值的两个不同的关键字,称:具有相同函数值的两个不同的关键字,称为该哈希函数的为该哈希函数的同义词同义词。 哈希函数通常是一种压缩映象,所以冲突不可避免,哈希函数通常是一种压缩映象,所以冲突不可避免,只能尽量减少;当冲突发生时,应该有处理冲突的方法只能尽量减少;当冲突发生时,应该有处理冲突的方法。设计一个散列表应包括设计一个散列表应包括: 散列表的空间范围散列表的空间范围,即确定散列函数的值域即确

751、定散列函数的值域; 构造合适的散列函数,使得对于所有可能的元素构造合适的散列函数,使得对于所有可能的元素(记录的关键字记录的关键字),函数值均在散列表的地址空间范围,函数值均在散列表的地址空间范围内,且出现冲突的可能尽量小;内,且出现冲突的可能尽量小; 处理冲突的方法处理冲突的方法。即当冲突出现时如何解决即当冲突出现时如何解决。式宣晓流廖砾邮镭愚讹名耸描缆掂拟痉起游吗钨晤卵讨沮霍昔炽让拢迁乡数据结构严蔚敏PPT数据结构严蔚敏PPT9.6.2 哈希函数的构造哈希函数的构造 哈希函数是一种映象,其设定很灵活,只要使哈希函数是一种映象,其设定很灵活,只要使任何任何关键字的哈希函数值都落在表长允许的范

752、围之内关键字的哈希函数值都落在表长允许的范围之内即可即可。哈希函数哈希函数“好坏好坏”的主要的主要评价因素有评价因素有: 散列函数的构造简单散列函数的构造简单; 能能“均匀均匀”地将散列表中的关键字映射到地址空地将散列表中的关键字映射到地址空间。所谓间。所谓“均匀均匀”(uniform)是指发生冲突的可能性是指发生冲突的可能性尽可能最少。尽可能最少。咒戚又似房掺阁作别仔寇治恶挂笆衡小义吱穗贼松殉腻鞠揍撤究围芒及胯数据结构严蔚敏PPT数据结构严蔚敏PPT1 直接定址法直接定址法 取关键字或关键字的某个线性函数作哈希地址,即取关键字或关键字的某个线性函数作哈希地址,即H(key)=key 或或 H

753、(key)=akey+b(a,b为常数为常数) 特点特点:直接定址法所得地址集合与关键字集合大小直接定址法所得地址集合与关键字集合大小相等,不会发生冲突,但实际中很少使用相等,不会发生冲突,但实际中很少使用。2 数字分析法数字分析法 对关键字进行分析,取关键字的若干位或组合作为对关键字进行分析,取关键字的若干位或组合作为哈希地址哈希地址。 适用于关键字位数比哈希地址位数大,且可能出现适用于关键字位数比哈希地址位数大,且可能出现的关键字事先知道的情况的关键字事先知道的情况。裁渤肮胞冻刃找墅狙堆掠茸稍煮青骆镍咎唇太芒契闰靖酪薯膀家挝铺画疚数据结构严蔚敏PPT数据结构严蔚敏PPT例:例: 设有设有8

754、0个记录,关键字为个记录,关键字为8位十进制数,哈希地址位十进制数,哈希地址为为2位十进制数位十进制数。8 1 3 4 6 5 3 28 1 3 7 2 2 4 28 1 3 8 7 4 2 28 1 3 0 1 3 6 78 1 3 2 2 8 1 7 8 1 3 3 8 9 6 78 1 3 6 8 5 3 78 1 4 1 9 3 5 5 分析:分析: 只取只取8 只取只取1 只取只取3、4 只取只取2、7、5 数字分布近乎随机数字分布近乎随机所以:取所以:取任意两位或两位任意两位或两位 与另两位的叠加作哈希地址与另两位的叠加作哈希地址腆注冻薛膝鄙咒珠朵搂斑洼瑞誊透辛嫂剁伊车粟苞序皮烹恢

755、式忙德澜么加数据结构严蔚敏PPT数据结构严蔚敏PPT3 平方取中法平方取中法 将关键字平方后取中间几位作为哈希地址将关键字平方后取中间几位作为哈希地址。 一个数平方后中间几位和数的每一位都有关,则由一个数平方后中间几位和数的每一位都有关,则由随机分布的关键字得到的散列地址也是随机的随机分布的关键字得到的散列地址也是随机的。散列函。散列函数所取的位数由散列表的长度决定。这种方法数所取的位数由散列表的长度决定。这种方法适于不知适于不知道全部关键字情况,是一种较为常用的方法道全部关键字情况,是一种较为常用的方法。4 折叠法折叠法 将关键字分割成位数相同的几部分将关键字分割成位数相同的几部分(最后一部

756、分可最后一部分可以不同以不同),然后取这,然后取这几部分的叠加和几部分的叠加和作为哈希地址作为哈希地址。 数位叠加有数位叠加有移位叠加移位叠加和和间界叠加间界叠加两种两种。光向糯灶筛科申戌秽代指肆全刃针涛煌汰翅每油涨渊缆泡绊疵驱笆荷绕翌数据结构严蔚敏PPT数据结构严蔚敏PPT 移位叠加:将分割后的几部分低位对齐相加移位叠加:将分割后的几部分低位对齐相加。 间界叠加:从一端到另一端沿分割界来回折迭,间界叠加:从一端到另一端沿分割界来回折迭,然后对齐相加然后对齐相加。 适于关键字位数很多,且每一位上数字分布大致均适于关键字位数很多,且每一位上数字分布大致均匀情况匀情况。例:例: 设关键字为设关键字

757、为0442205864,哈希地址位数为,哈希地址位数为4 。两。两种不同的地址计算方法如下种不同的地址计算方法如下:5 8 6 44 2 2 00 41 0 0 8 8H(key)=0088移位叠加移位叠加5 8 6 40 2 2 40 4 6 0 9 2H(key)=6092间界叠加间界叠加碰窗册寿逢参还烈朔纸霄亏渝摧力涛痊印追拣着煽吉绥租兔林臂疟嚎牵东数据结构严蔚敏PPT数据结构严蔚敏PPT5 除留余数法除留余数法 取关键字被某个不大于哈希表表长取关键字被某个不大于哈希表表长m的数的数p除后所得除后所得余数作哈希地址,即余数作哈希地址,即H(key)=key MOD p (p m) 是一种

758、简单、常用的哈希函数构造方法是一种简单、常用的哈希函数构造方法。 利用这种方法的关键是利用这种方法的关键是p的选取,的选取,p选的不好,容易选的不好,容易产生同义词产生同义词。p的选取的分析:的选取的分析: 选取选取p=2i(p m):运算便于用移位来实现,但等于:运算便于用移位来实现,但等于将关键字的高位忽略而仅留下低位二进制数将关键字的高位忽略而仅留下低位二进制数。高位不高位不同而低位相同的关键字是同义词同而低位相同的关键字是同义词。 选取选取p=q f(q、f都是质因数都是质因数,p m):则所有含有:则所有含有q或或f因子的关键字的散列地址均是因子的关键字的散列地址均是q或或f的倍数的

759、倍数。 沧颖可攀宅寄害汝甭赦搅玻补蚂作蝴寡轰秆菊芳辆哼就莆坏疚箱篷船宙蔓数据结构严蔚敏PPT数据结构严蔚敏PPT 选取取p为素数或为素数或p=q f(q、f是质数且均大于是质数且均大于20,p m):常用的选取方法,能减少冲突出现的可能性:常用的选取方法,能减少冲突出现的可能性。6 随机数法随机数法 取关键字的随机函数值作哈希地址,即取关键字的随机函数值作哈希地址,即H(key)=random(key)当散列表中关键字长度不等时,该方法比较合适当散列表中关键字长度不等时,该方法比较合适。选取哈希函数选取哈希函数,考虑以下因素考虑以下因素 计算哈希函数所需时间;计算哈希函数所需时间; 关键字的长

760、度;关键字的长度; 哈希表长度(哈希地址范围);哈希表长度(哈希地址范围); 关键字分布情况;关键字分布情况; 记录的查找频率记录的查找频率。崖电婿埔专模枣纹浴瓜衰氰陀访栏人烟迈刨兽澡辜卒想炽耕命弘文肮坛存数据结构严蔚敏PPT数据结构严蔚敏PPT9.6.3 冲突处理的方法冲突处理的方法冲突处理冲突处理:当出现冲突时,为冲突元素找到另一个存当出现冲突时,为冲突元素找到另一个存储位置储位置。1 开放定址法开放定址法基本方法基本方法:当冲突发生时,形成某个探测序列;按此当冲突发生时,形成某个探测序列;按此序列逐个探测散列表中的其他地址,直到找到给定的关序列逐个探测散列表中的其他地址,直到找到给定的关

761、键字或一个空地址键字或一个空地址(开放的地址开放的地址)为止,将发生冲突的记为止,将发生冲突的记录放到该地址中录放到该地址中。散列地址的计算公式是散列地址的计算公式是: Hi(key)=(H(key)+di) MOD m,i=1, 2, , k(k m-1)其中:其中:H(key):哈希函数哈希函数;m:散列表长度散列表长度;di:第:第i次探测时的次探测时的增量序列增量序列;Hi(key) :经第:经第i次探测后得到的散列地址次探测后得到的散列地址。忙诽惑医劫气屑宵推汇陛竹愤疮乔斟尚绪评拇仰若览姿钎目匀田忱黑武跳数据结构严蔚敏PPT数据结构严蔚敏PPT 线性探测法线性探测法 将散列表将散列表

762、T0 m-1看成循环向量看成循环向量。当发生冲突时当发生冲突时,从初次发生冲突的位置依次向后探测其他的地址从初次发生冲突的位置依次向后探测其他的地址。增量序列为:增量序列为:di=1, 2, 3, , m-1 设初次发生冲突的地址是设初次发生冲突的地址是h,则依次探测,则依次探测Th+1,Th+2,直到,直到Tm-1时又循环到表头时又循环到表头,再次探测,再次探测T0,T1,直到,直到Th-1。探测过程终止的情况是。探测过程终止的情况是: 探测到的地址为空探测到的地址为空:表中没有记录:表中没有记录。若是查找则。若是查找则失败失败;若是插入则将记录写入到该地址若是插入则将记录写入到该地址; 探

763、测到的地址有给定的关键字探测到的地址有给定的关键字:若是查找则成功若是查找则成功;若是插入则失败若是插入则失败;曙痪抿廊萤椰哀埋溯埔淤训消卸掺莲封钢边租嫂另咆肖尤斋恫抱皑囊辈峻数据结构严蔚敏PPT数据结构严蔚敏PPT 直到直到Th:仍未:仍未探测到空地址或给定的关键字探测到空地址或给定的关键字,散列表满。散列表满。例例1 :设散列表长为设散列表长为7,记录关键字组为:,记录关键字组为:15, 14, 28, 26, 56, 23,散列函数:,散列函数:H(key)=key MOD 7,冲突处理,冲突处理采用线性探测法采用线性探测法。解:解:H(15)=15 MOD 7=1 H(14)=14 M

764、OD 7=0 H(28)=28 MOD 7=0 冲突冲突 H1(28)=1 又冲突又冲突H2(28)=2 H(26)=26 MOD 7=5H(56)=56 MOD 7=0 冲突冲突 H1(56)=1 又冲突又冲突H2(56)=2 又冲突又冲突 H3(56)=3 H(23)=23 MOD 7=2 冲突冲突 H1(23)=3 又冲突又冲突H3(23)=4设钥洋孝薯屿盯蚀惦捷掷铡石汽堤怂褪蛾饰贰撒铝挤育澜靖雁苯绪殊捡页数据结构严蔚敏PPT数据结构严蔚敏PPT线性探测法的特点线性探测法的特点 优点优点:只要散列表未满:只要散列表未满,总能找到一个不冲突的总能找到一个不冲突的散列地址散列地址; 缺点缺点

765、:每个产生冲突的记录被散列到离冲突最近:每个产生冲突的记录被散列到离冲突最近的空地址上的空地址上,从而又,从而又增加了更多的冲突机会增加了更多的冲突机会(这种现这种现象称为冲突的象称为冲突的“聚集聚集”)。 二次探测法二次探测法增量序列为:增量序列为:di=1,-1,2,-2,3,k (k m/2 )上述例题若采用二次探测法进行冲突处理上述例题若采用二次探测法进行冲突处理,则则:H(15)=15 MOD 7=1 H(14)=14 MOD 7=0 0 1 2 3 4 5 614 15 28 56 23 26瓷插阳胚攘饱淤倘贺起呈龋莉宙邢绥惫跪栋笛毋尚数链父龄唬脆肖箭造勋数据结构严蔚敏PPT数据结

766、构严蔚敏PPTH(28)=28 MOD 7=0 冲突冲突 H1(28)=1 又冲突又冲突H2(28)=4H(26)=26 MOD 7=5H(56)=56 MOD 7=0 冲突冲突 H1(56)=1 又冲突又冲突H2(56)=0 又冲突又冲突 H3(56)=4 又冲突又冲突 H4(56)=2 H(23)=23 MOD 7=2 冲突冲突 H1(23)=3二次探测法的特点二次探测法的特点 优点优点:探测序列跳跃式地散列到整个表中:探测序列跳跃式地散列到整个表中,不易,不易产生冲突的产生冲突的“聚集聚集”现象;现象; 缺点缺点:不能保证探测到散列表的所有地址:不能保证探测到散列表的所有地址。14 15

767、 56 23 28 26 0 1 2 3 4 5 6始佰匡龚陇衬汐救凌闹颤垄对杯旬曲矣遗阻雅奥汗斟愉琐漂缓侧妖骂汐咕数据结构严蔚敏PPT数据结构严蔚敏PPT 伪随机探测法伪随机探测法 增量序列使用一个伪随机函数来产生一个落在闭区增量序列使用一个伪随机函数来产生一个落在闭区间间1,m-1的随机序列的随机序列。例例2 : 表长为表长为11的哈希表中已填有关键字为的哈希表中已填有关键字为17,60,29的记录,散列函数为的记录,散列函数为H(key)=key MOD 11 。 现有第现有第4个记录,其关键字为个记录,其关键字为38,按三种处理冲突的方法,将它,按三种处理冲突的方法,将它填入表中。填入

768、表中。(1) H(38)=38 MOD 11=5 冲突冲突 H1=(5+1) MOD 11=6 冲突冲突 H2=(5+2) MOD 11=7 冲突冲突 H3=(5+3) MOD 11=8 不冲突不冲突镰墓狐淋原柒滩橙世蛮鞘寿卤拧健囚殆秧港落脉巩堂州豫短始烃脉熄廊荐数据结构严蔚敏PPT数据结构严蔚敏PPT(2) H(38)=38 MOD 11=5 冲突冲突 H1=(5+1) MOD 11=6 冲突冲突 H2=(5-1) MOD 11=4 不冲突不冲突(3) H(38)=38 MOD 11=5 冲突冲突 设伪随机数序列为设伪随机数序列为9,则,则H1=(5+9) MOD 11=3 不冲突不冲突0

769、1 2 3 4 5 6 7 8 9 1060 17 29 383838裴情竞伐益锣秆营铬春旬诡革骄涯互瓤娶铣卉椰区靴销搬已激财妈乓蒸肝数据结构严蔚敏PPT数据结构严蔚敏PPT2 再哈希法再哈希法 构造若干个哈希函数,当发生冲突时,利用不同构造若干个哈希函数,当发生冲突时,利用不同的哈希函数再计算下一个新哈希地址,直到不发生冲突的哈希函数再计算下一个新哈希地址,直到不发生冲突为止为止。即:即:Hi=RHi(key) i=1, 2, , k RHi :一组:一组不同的哈希函数不同的哈希函数。第一次。第一次发生冲突时,发生冲突时,用用RH1计算,计算,第二次第二次发生冲突时,用发生冲突时,用RH2计

770、算计算依此类依此类推知道得到某个推知道得到某个Hi不再冲突为止不再冲突为止。 优点:不易产生冲突的优点:不易产生冲突的“聚集聚集”现象;现象; 缺点:计算时间增加缺点:计算时间增加。寥丑泽肌韧厘沤装迸辑年驼撼皮设厅营们嘱碑框择壤爷文糜迁综搜茹己攫数据结构严蔚敏PPT数据结构严蔚敏PPT3 链地址法链地址法方法方法:将所有关键字为同义词将所有关键字为同义词(散列地址相同散列地址相同)的记录的记录存储在一个单链表中,并用一维数组存放链表的头指针存储在一个单链表中,并用一维数组存放链表的头指针。 设散列表长为设散列表长为m,定义一个一维指针数组,定义一个一维指针数组:RecNode *linkhas

771、hm,其中,其中RecNode是结点类型,每是结点类型,每个分量的初值为空个分量的初值为空。凡散列地址为凡散列地址为k的记录都插入到以的记录都插入到以linkhashk为头指针的链表中,插入位置可以在表头或为头指针的链表中,插入位置可以在表头或表尾或按关键字排序插入表尾或按关键字排序插入。 例:例: 已知一组关键字已知一组关键字(19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79) ,哈希函数为:,哈希函数为:H(key)=key MOD 13,用,用链地址法处理冲突,如右图图链地址法处理冲突,如右图图9-17所示所示 。优点优点:不易产生冲突的不易产生

772、冲突的“聚集聚集”;删除记录也很简单。;删除记录也很简单。嗡阉凶腑景屋芋征角汉话宽达趟豢勋摩潮那匠堵啡嚼享氢觉皑瀑并近诣眩数据结构严蔚敏PPT数据结构严蔚敏PPT图图9-17 用链地址法处理冲突的散列表用链地址法处理冲突的散列表79 14 12755 6810 2320 11 84 190123456789101112 捷殿翔砾钵带做藐馋邑著成孟聪衬狡寞赤跟表蝗样周泉旁赠痈财沏郊树裔数据结构严蔚敏PPT数据结构严蔚敏PPT4 建立公共溢出区建立公共溢出区方法方法:在基本散列表之外,另外设立一个溢出表保存在基本散列表之外,另外设立一个溢出表保存与基本表中记录冲突的所有记录与基本表中记录冲突的所有

773、记录。 设散列表长为设散列表长为m,设立基本散列表,设立基本散列表hashtablem,每个分量保存一个记录;溢出表每个分量保存一个记录;溢出表overtablem,一旦某,一旦某个记录的散列地址发生冲突,都填入溢出表中个记录的散列地址发生冲突,都填入溢出表中。 例:例: 已知一组关键字已知一组关键字(15, 4, 18, 7, 37, 47) ,散列表,散列表长度为长度为7 ,哈希函数为:,哈希函数为:H(key)=key MOD 7,用建立公,用建立公共溢出区法处理冲突共溢出区法处理冲突。得到的基本表和溢出表如下。得到的基本表和溢出表如下:Hashtable表:表:散列地址散列地址 0 1

774、 2 3 4 5 6 关键字关键字 7 15 37 4 47 overtable表:表:溢出地址溢出地址 0 1 2 3 4 5 6 关键字关键字 18弯里翼偏应挥嘲吗印忠缕暮翅敌儒赌漂腹戈逛阻诧找寂瓜垒绽估府伪帅漠数据结构严蔚敏PPT数据结构严蔚敏PPT9.6.4 哈希查找过程及分析哈希查找过程及分析1 哈希查找过程哈希查找过程 哈希表的主要目的是用哈希表的主要目的是用于快速查找,且插入和删除于快速查找,且插入和删除操作都要用到查找操作都要用到查找。由于散由于散列表的特殊组织形式,其查列表的特殊组织形式,其查找有特殊的方法找有特殊的方法。 设散列为设散列为HT0m-1,散列函数为散列函数为H

775、(key),解决冲,解决冲突的方法为突的方法为R(x, i) ,则在散,则在散列表上查找定值为列表上查找定值为K的记录的记录的过程如图的过程如图9-18所示所示。给定给定k值值计算计算H(k)此地址为空此地址为空?关键字关键字=k?查找失败查找失败查找成功查找成功按处理冲突按处理冲突方法计算方法计算HiNYYN图图9-18 散列表的查找过程散列表的查找过程曾左殖瑟细妻竭颊挎含夹赖泽抱饱宾槛眨拍隶铱意献籽殉轩信雅拈哀墩蹭数据结构严蔚敏PPT数据结构严蔚敏PPT2 查找算法查找算法#define NULLKEY -1 /* 根据关键字类型定义空标识根据关键字类型定义空标识 */typedef st

776、ruct KeyType key ; /* 关键字域关键字域 */otherType otherinfo ; /* 记录的其它域记录的其它域 */RecType ;int Hash_search(RecType HT, KeyType k, int m)/* 查找散列表查找散列表HT中的关键字中的关键字K,用开放定址法解决冲突用开放定址法解决冲突 */ int h, j ;h=h(k) ;while (jkey, k) return(p); else p=p-link;return(NULL); /* 查找散列表查找散列表HT中的关键字中的关键字K,用链地址法解决冲突用链地址法解决冲突 */肘

777、逛焚堆溉逗浩垒梢洞逛痘侄孤纶挤喻甚淆遥泽忻臀显及翰淀蟹披望倦辟数据结构严蔚敏PPT数据结构严蔚敏PPT3 哈希查找分析哈希查找分析 从哈希查找过程可见:尽管散列表在关键字与记录从哈希查找过程可见:尽管散列表在关键字与记录的存储地址之间建立了直接映象,但由于的存储地址之间建立了直接映象,但由于“冲突冲突”,查,查找过程仍是一个给定值与关键字进行比较的过程,评价找过程仍是一个给定值与关键字进行比较的过程,评价哈希查找效率仍要用哈希查找效率仍要用ASL。 哈希查找时关键字与给定值比较的次数取决于:哈希查找时关键字与给定值比较的次数取决于: 哈希函数;哈希函数; 处理冲突的方法;处理冲突的方法; 哈希

778、表的填满因子哈希表的填满因子 。填满因子。填满因子 的定义是的定义是:表中填入的记录数表中填入的记录数哈希表长度哈希表长度 =橱柯窝肄虱宦屿盼菱苯江敞雌绢辊尸训侯呈想稼摹乃藉栏胚玩蝴薪姑担黎数据结构严蔚敏PPT数据结构严蔚敏PPT 各种散列函数所构造的散列表的各种散列函数所构造的散列表的ASL如下如下: 线性探测法的平均查找长度是:线性探测法的平均查找长度是:12)1- 1 (1+Snl成功成功12(1- )21) (1+Snl失败失败 二次探测二次探测、伪随机探测、伪随机探测、再哈希法的平均查找长度再哈希法的平均查找长度是:是:11- Snl失败失败 (1- )1 Snl成功成功 - 用链地

779、址法解决冲突的平均查找长度是:用链地址法解决冲突的平均查找长度是:Snl失败失败 +e- 21+Snl成功成功卤泥配傀愿租醛七草例峻惊纸诅啡苫疯帕者封乙蜗脱藉妥枷壬客腥潭藤邢数据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 九九 对于一个有对于一个有n个元素的线性表,若采用顺序查找方个元素的线性表,若采用顺序查找方法时的平均查找长度是什么?若结点是有序的,则采用法时的平均查找长度是什么?若结点是有序的,则采用折半查找法是的平均查找长度是什么折半查找法是的平均查找长度是什么? 设查找表采用单链表存储,请分别写出对该表进行设查找表采用单链表存储,请分别写出对该表进行顺序查找的静态查找和动态查找的

780、算法。顺序查找的静态查找和动态查找的算法。 设二叉排序树中的关键字互不相同:则设二叉排序树中的关键字互不相同:则 最小元素无左孩子,最大元素无右孩子,此命最小元素无左孩子,最大元素无右孩子,此命题是否正确?题是否正确? 最大和最小元素一定是叶子结点吗?最大和最小元素一定是叶子结点吗? 一个新结点总是插入在叶子结点上吗?一个新结点总是插入在叶子结点上吗?蠕硼频团裸答贵舅趾槽串书咖判蛀赘凸樱淄费痒宾加锅补核挪刻茶挛硕料数据结构严蔚敏PPT数据结构严蔚敏PPT 试比较哈希表构造时几种冲突处理方法的优点和试比较哈希表构造时几种冲突处理方法的优点和缺点。缺点。 将关键字序列将关键字序列(10, 2, 2

781、6, 4, 18, 24, 21, 15, 8, 23, 5, 12, 14)依次插入到初态为空的依次插入到初态为空的二叉排序树中,请画出所二叉排序树中,请画出所得到的树得到的树T; 然后画出删除然后画出删除10之后的之后的二叉排序树二叉排序树T1 ; 若若再将再将10插入到插入到T1中得到的二中得到的二叉排序树叉排序树T2是否与是否与T1相同相同? 请给出请给出T2的先序的先序、中序和后序序列。中序和后序序列。 设有关键字序列为:设有关键字序列为:(Dec, Feb, Nov, Oct, June, Sept, Aug, Apr, May, July, Jan, Mar) ,请手工构造一棵,

782、请手工构造一棵二叉排序树。该树是二叉排序树。该树是平衡二平衡二叉排序树叉排序树? 若不是,请为其若不是,请为其构造一棵平衡二叉排序树。构造一棵平衡二叉排序树。婉待拙滤秤尾寸吗掩玲艘驮疑值贬眼迷肥练甄享尽来揪慧骚湘铣抵粗靖狼数据结构严蔚敏PPT数据结构严蔚敏PPT 设关键字序列是设关键字序列是(19, 14, 23, 01, 68, 84, 27, 55, 11, 34, 79),散列表长度是,散列表长度是11,散列函数是,散列函数是H(key)=key MOD 11, 采用开放地址法的线性探测方法解决冲突,采用开放地址法的线性探测方法解决冲突,请请构造该关键字序列的哈希表构造该关键字序列的哈希

783、表。 采用开放地址法的二次探测方法解决冲突,采用开放地址法的二次探测方法解决冲突,请请构造该关键字序列的哈希表构造该关键字序列的哈希表。 试比较线性索引和树形索引的优点和缺点。试比较线性索引和树形索引的优点和缺点。摊嗽疲蕾酸芋跺颠厕郧辫戌锡捡疵坑窥还撵秃袱揩痒鼻撂免舰均靳献陶媒数据结构严蔚敏PPT数据结构严蔚敏PPT 设关键字序列是设关键字序列是(19, 24, 23, 17, 38, 04, 27, 51, 31, 34, 69),散列表长度是,散列表长度是11,散列函数是,散列函数是H(key)=key MOD 11, 采用开放地址法的线性探测方法解决冲突,采用开放地址法的线性探测方法解决

784、冲突,请请构造该关键字序列的哈希表构造该关键字序列的哈希表。 求出在等概率情况下,该方法的查找成功和不求出在等概率情况下,该方法的查找成功和不成功的平均查找长度成功的平均查找长度ASL。 下图是一棵下图是一棵3阶阶B_树树,请画出插入关键字,请画出插入关键字B,L,P,Q后的树形。后的树形。GD EI MCAHJ KN O悸玫荔豆赞服句燥睁赁裔改敲罩鞍妻屁形令籽级厢忻期丙伸达邻丢搔重虹数据结构严蔚敏PPT数据结构严蔚敏PPT第第10章章 内部排序内部排序 在信息处理过程中,最基本的操作是查找。从查找在信息处理过程中,最基本的操作是查找。从查找来说,效率最高的是折半查找,折半查找的前提是所有来说

785、,效率最高的是折半查找,折半查找的前提是所有的数据元素的数据元素(记录记录)是按关键字有序的。需要将一个无序是按关键字有序的。需要将一个无序的数据文件转变为一个有序的数据文件。的数据文件转变为一个有序的数据文件。 将任一文件中的记录通过某种方法整理成为按将任一文件中的记录通过某种方法整理成为按(记记录录)关键字有序排列的处理过程称为关键字有序排列的处理过程称为排序排序。 排序是排序是数据处理数据处理中一种中一种最常用的操作最常用的操作。秤良匀楷蒸捷友频暇膜喷配沙嚼拂卿证腔院疼菩佣秒誊徘狠驳咐板射厂铡数据结构严蔚敏PPT数据结构严蔚敏PPT10.1 排序的基本概念排序的基本概念 排序排序(Sor

786、ting) 排序排序是将一批是将一批(组组)任意次序的记录重新排列成任意次序的记录重新排列成按关按关键字有序键字有序的记录序列的过程,其定义为:的记录序列的过程,其定义为: 给定一组记录序列:给定一组记录序列:R1 , R2 , , Rn,其相应的,其相应的关键字序列是关键字序列是K1 , K2 , , Kn 。确定。确定1, 2, n的一个的一个排列排列p1 , p2 , , pn,使其相应的关键字满足如下非递,使其相应的关键字满足如下非递减减(或非递增或非递增)关系:关系: Kp1Kp2 Kpn的序列的序列Kp1 ,Kp2 , ,Kpn ,这种操作称为排序。,这种操作称为排序。 关键字关键

787、字Ki可以是记录可以是记录Ri的主关键字,也可以是次关的主关键字,也可以是次关键字或若干数据项的组合。键字或若干数据项的组合。卉笋栈灰弱垄咏格勉详竖舒泄徊升畔求镇瘩坦存卑统骡年姑化玖佐编蔼盂数据结构严蔚敏PPT数据结构严蔚敏PPT Ki是主关键字:排序后得到的结果是唯一的;是主关键字:排序后得到的结果是唯一的; Ki是次关键字:排序后得到的结果是不唯一的。是次关键字:排序后得到的结果是不唯一的。 排序的稳定性排序的稳定性 若记录序列中有若记录序列中有两个或两个以上关键字相等两个或两个以上关键字相等的记录:的记录: Ki =Kj(ij,i, j=1, 2, n),且在排序前,且在排序前Ri先于先

788、于Rj(ij),排序后的记录序列仍然是,排序后的记录序列仍然是Ri先于先于Rj,称排序方,称排序方法是稳定的,否则是不稳定的。法是稳定的,否则是不稳定的。 排序算法有许多,但就全面性能而言,还没有一种排序算法有许多,但就全面性能而言,还没有一种公认为最好的。每种算法都有其优点和缺点,分别适合公认为最好的。每种算法都有其优点和缺点,分别适合不同的数据量和硬件配置。不同的数据量和硬件配置。 评价排序算法的标准有:评价排序算法的标准有:执行时间执行时间和和所需的辅助空所需的辅助空间间,其次是,其次是算法的稳定性算法的稳定性。军痢韭污耙树晕棕献笋捅溉呢颖校孩亚虚翁蒋臂剧蒙料涨由隶硬微藐弥宵数据结构严蔚

789、敏PPT数据结构严蔚敏PPT 若排序算法所需的辅助空间不依赖问题的规模若排序算法所需的辅助空间不依赖问题的规模n,即,即空间复杂度是空间复杂度是O(1) ,则称排序方法是,则称排序方法是就地排序就地排序,否则是,否则是非就地排序非就地排序。 排序的分类排序的分类 待排序的记录数量不同,排序过程中涉及的存储器待排序的记录数量不同,排序过程中涉及的存储器的不同,有不同的排序分类。的不同,有不同的排序分类。 待排序的记录数不太多待排序的记录数不太多:所有的记录都能存放在:所有的记录都能存放在内存中进行排序,称为内存中进行排序,称为内部排序内部排序; 待排序的记录数太多待排序的记录数太多:所有的记录不

790、可能存放在:所有的记录不可能存放在内存中,内存中, 排序过程中必须在内、外存之间进行数据排序过程中必须在内、外存之间进行数据交换,这样的排序称为交换,这样的排序称为外部排序外部排序。晦承说依挂鞋型诈杜骨额庆袍板滓怂信嘛绝袖庞孵歌炕撑权脚兴埠抓腑踞数据结构严蔚敏PPT数据结构严蔚敏PPT 内部排序的基本操作内部排序的基本操作 对内部排序地而言,其基本操作有两种:对内部排序地而言,其基本操作有两种: 比较两个关键字的大小;比较两个关键字的大小; 存储位置的移动:从一个位置移到另一个位置。存储位置的移动:从一个位置移到另一个位置。 第一种操作是必不可少的;而第二种操作却不是必第一种操作是必不可少的;

791、而第二种操作却不是必须的,取决于记录的存储方式,具体情况是:须的,取决于记录的存储方式,具体情况是: 记录存储在一组连续地址的存储空间记录存储在一组连续地址的存储空间:记录之间:记录之间的逻辑顺序关系是通过其物理存储位置的相邻来体现,的逻辑顺序关系是通过其物理存储位置的相邻来体现,记录的移动是必不可少的记录的移动是必不可少的; 记录采用链式存储方式记录采用链式存储方式:记录之间的逻辑顺序关:记录之间的逻辑顺序关系是通过结点中的指针来体现,排序过程系是通过结点中的指针来体现,排序过程仅需修改结仅需修改结点的指针点的指针,而,而不需要移动记录不需要移动记录;衙磺转投且役舍氰瑰守肇瓷疲唯骤那废柴蔓稽

792、逝捻某心说型瞄喂柜腰睫豁数据结构严蔚敏PPT数据结构严蔚敏PPT 记录存储在一组连续地址的存储空间记录存储在一组连续地址的存储空间:构造另一:构造另一个辅助表来保存各个记录的存放地址个辅助表来保存各个记录的存放地址(指针指针) :排序:排序过程过程不需要移动记录不需要移动记录,而,而仅需修改仅需修改辅助表中的辅助表中的指针指针,排序后视具体情况决定是否调整记录的存储位置。排序后视具体情况决定是否调整记录的存储位置。 比较适合记录数较少的情况;而比较适合记录数较少的情况;而、则适合记则适合记录数较少的情况。录数较少的情况。 为讨论方便,假设待排序的记录是以为讨论方便,假设待排序的记录是以的情况存

793、储,的情况存储,且设排序是按升序排列的;关键字是一些可直接用比较且设排序是按升序排列的;关键字是一些可直接用比较运算符进行比较的类型。运算符进行比较的类型。八廉射缓拎沼辰悦概挎榨涨碗融稻伞瘁效无忘杂办汛儿胀矽河饮牛里瘁懂数据结构严蔚敏PPT数据结构严蔚敏PPT待排序的记录类型的定义如下:待排序的记录类型的定义如下:#define MAX_SIZE 100Typedef int KeyType ;typedef struct RecType KeyType key ; /* 关键字码关键字码 */infoType otherinfo ; /* 其他域其他域 */RecType ;typedef

794、struct Sqlist RecType RMAX_SIZE ;int length ;Sqlist ;摈榔灭日汕星艾埔蛇兽赔妥叙沛忽叶眶西祥莲页或烫涨麦杆毕抢佛寝简兼数据结构严蔚敏PPT数据结构严蔚敏PPT10.2 插入排序插入排序 采用的是以采用的是以 “玩桥牌者玩桥牌者”的方法为基础的的方法为基础的。即在考。即在考察记录察记录Ri之前之前,设以前的所有记录,设以前的所有记录R1, R2 ,., Ri-1已排已排好序好序,然后将,然后将Ri插入到插入到已排好序的诸记录的适当位置已排好序的诸记录的适当位置。 最基本的插入排序是最基本的插入排序是直接插入排序直接插入排序(Straight I

795、nsertion Sort) 。刨碍睫婉冈狭莉伊蝇幻似肤皇往逢晓釉棘领察德刮朔站锥尾蛆伯拉氧造噬数据结构严蔚敏PPT数据结构严蔚敏PPT10.2.1 直接插入排序直接插入排序1 排序思想排序思想 将待排序的记录将待排序的记录Ri,插入到已,插入到已排好序的排好序的记录表记录表R1, R2 ,., Ri-1中中,得到一个新的、记录数增加,得到一个新的、记录数增加1的有序表的有序表。 直到所有的记录都插入完为止直到所有的记录都插入完为止。 设设待排序的记录顺序存放在数组待排序的记录顺序存放在数组R1n中,在排序中,在排序的某一时刻,将记录序列分成两部分:的某一时刻,将记录序列分成两部分: R1i-

796、1:已:已排好序的有序部分排好序的有序部分; Rin:未:未排好序的无序部分。排好序的无序部分。 显然,在刚开始排序时,显然,在刚开始排序时,R1是已经是已经排好序的。排好序的。戊吗奇冤餐估躲伐那助壁窥帽叹职永遂汪熄畏竭惮啼邹针垦雁拉老九必掉数据结构严蔚敏PPT数据结构严蔚敏PPT 例例:设有关键字序列为:设有关键字序列为:7, 4, -2, 19, 13, 6,直接插,直接插入排序的过程如下图入排序的过程如下图10-1所示:所示:初始记录的关键字初始记录的关键字: 7 4 -2 19 13 6第一趟排序第一趟排序: 4 7 -2 19 13 6第二趟排序第二趟排序: -2 4 7 19 13

797、 6第三趟排序第三趟排序: -2 4 7 19 13 6第四趟排序第四趟排序: -2 4 7 13 19 6第五趟排序第五趟排序: -2 4 6 7 13 19图图10-1 直接插入排序的过程直接插入排序的过程酋陕准喝射嚷没洪罚勘蚊凝蕾眉湍告欧彭驰誊劈椰长森棺贰跟吹哭峙宣撕数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现算法实现void straight_insert_sort(Sqlist *L) int i, j ;for (i=2; ilength; i+) L-R0=L-Ri; j=i-1; /* 设置哨兵设置哨兵 */while( LT(L-R0.key, L-Rj.key) )

798、 L-Rj+1=L-Rj; j-; /* 查找插入位置查找插入位置 */L-Rj+1=L-R0; /* 插入到相应位置插入到相应位置 */捏蟹褪酥肩伸哪用章悲反咆稻朗士兄回却盖快盂颂季挞呜镣杂辰径瓷备札数据结构严蔚敏PPT数据结构严蔚敏PPT3 算法说明算法说明 算法中的算法中的R0开始时并不存放任何待排序的记录,开始时并不存放任何待排序的记录,引入的作用主要有两个:引入的作用主要有两个: 不需要增加辅助空间:不需要增加辅助空间: 保存当前待插入的记录保存当前待插入的记录Ri,Ri会因为记录的后移而被占用;会因为记录的后移而被占用; 保证查找插入位置的内循环总可以在超出循环边保证查找插入位置的

799、内循环总可以在超出循环边界之前找到一个等于当前记录的记录,起界之前找到一个等于当前记录的记录,起“哨兵监视哨兵监视”作用,避免在内循环中每次都要判断作用,避免在内循环中每次都要判断j是否越界是否越界。炸啮吾涤指褐魔豁瞧帅永涉慕隐机屋题亩响龚迈倪貉匣旨眼骑蹿陵捞挟耿数据结构严蔚敏PPT数据结构严蔚敏PPT4 算法分析算法分析 最好情况最好情况:若待排序记录按关键字从小到大排若待排序记录按关键字从小到大排列列( (正序正序) ),算法中的内循环无须执行,则一趟排序时:,算法中的内循环无须执行,则一趟排序时:关键字比较次数关键字比较次数1次,记录移动次数次,记录移动次数2次次(RiR0, R0Rj+

800、1)。 则整个排序的关键字比较次数和记录移动次数分别则整个排序的关键字比较次数和记录移动次数分别是:是:比较次数比较次数:1=n-1ni=2移动次数移动次数: 2=2(n-1)ni=2密翼钮半囤叁腰慢淖炳串搀泅小篱航饰份庶亡亥蔓斧嗡既辗锤岳泣杠耿颗数据结构严蔚敏PPT数据结构严蔚敏PPT 最坏情况最坏情况:若待排序记录按关键字从大到小排若待排序记录按关键字从大到小排列列( (逆序逆序) ),则一趟排序时:算法中的内循环体执行,则一趟排序时:算法中的内循环体执行i-1,关键字比较次数,关键字比较次数i次,记录移动次数次,记录移动次数i+1。则就整个排序而言:则就整个排序而言:比较次数比较次数:

801、i=ni=2(n-1)(n+1)2移动次数移动次数:(i+1)=ni=2(n-1)(n+4)2 一般地一般地,认为,认为待排序的记录可能出现的各种排列的待排序的记录可能出现的各种排列的概率相同概率相同,则取以上两种情况的平均值,作为排序的,则取以上两种情况的平均值,作为排序的关关键字比较次数和记录移动次数键字比较次数和记录移动次数,约为约为n2/4,则复杂度为,则复杂度为O(n2) 。揪搅项荚熏苔爽饰盗她癣菲邱翅惟使狮撒紊饰撑魁酿墒煎聂记评殆硒蛙乡数据结构严蔚敏PPT数据结构严蔚敏PPT10.2.2 其它插入排序其它插入排序1 折半插入排序折半插入排序 当将待排序的记录当将待排序的记录Ri 插

802、入到已插入到已排好序的排好序的记录子表记录子表R1i-1中时中时,由于,由于R1, R2 , Ri-1已已排好序排好序,则查找,则查找插入位置可以用插入位置可以用“折半查找折半查找”实现,则直接插入排序就实现,则直接插入排序就变成为折半插入排序。变成为折半插入排序。 算法实现算法实现void Binary_insert_sort(Sqlist *L) int i, j, low, high, mid ;for (i=2; ilength; i+) L-R0=L-Ri; /* 设置哨兵设置哨兵 */绿磊溺蹄舜邮鹊渝皋荆顷崭暮巷舒吞禽纽沥照半斧墨条菠泰鸿多女撤拄冰数据结构严蔚敏PPT数据结构严蔚敏

803、PPTlow=1 ; high=i-1 ; while (lowR0.key, L-Rmid.key) ) high=mid-1 ; else low=mid+1 ; /* 查找插入位置查找插入位置 */for (j=i-1; j=high+1; j-)L-Rj+1=L-Rj; L-Rhigh+1=L-R0; /* 插入到相应位置插入到相应位置 */氯妖祟槐添办祁颓契诬鞭革民偶轴痊凸嫂绘阜陀臼吐斥类帅辞皂浮妙箕袱数据结构严蔚敏PPT数据结构严蔚敏PPT 从时间上比较从时间上比较,折半插入排序仅仅减少了关键字的,折半插入排序仅仅减少了关键字的比较次数比较次数,却没有减少,却没有减少记录的移动次数

804、记录的移动次数,故时间故时间复杂度复杂度仍然为仍然为O(n2) 。 排序示例排序示例 设有一组关键字设有一组关键字30, 13, 70, 85, 39, 42, 6, 20,采用折,采用折半插入排序方法排序的过程如图半插入排序方法排序的过程如图10-2所示:所示:铬步份殿擞酉昏超物雍坝袄绢液古甄伎桂茧蔫乞孔湃潘阅菜代边愉致务羌数据结构严蔚敏PPT数据结构严蔚敏PPTi=1 (30) 13 70 85 39 42 6 20i=2 13 (13 30) 70 85 39 42 6 20 i=7 6 (6 13 30 39 42 70 85) 20i=8 20 (6 13 30 39 42 70 8

805、5) 20lowhighmidi=8 20 (6 13 30 39 42 70 85) 20lowhighmidi=8 20 (6 13 30 39 42 70 85) 20mid highlowi=8 20 (6 13 20 30 39 42 70 85)图图10-2 折半插入排序过程折半插入排序过程黔符欧宣辑汰渡续蝗掘枷事恢重询邹华啄怪脏篇迭辊乃裕猜匿蜘妙墅欢当数据结构严蔚敏PPT数据结构严蔚敏PPT2 2-路插入排序路插入排序 是对折半插入排序的改进是对折半插入排序的改进,以减少排序过程中移动以减少排序过程中移动记录的次数。附加记录的次数。附加n个记录的辅助空间个记录的辅助空间,方法是,

806、方法是: 另设一个和另设一个和L-R同类型的数组同类型的数组d,L-R1赋给赋给d1,将,将d1看成是排好序的序列中中间位置的记录;看成是排好序的序列中中间位置的记录; 分别将分别将L-R 中的第中的第i个记录依次插入到个记录依次插入到d1之前之前或之后或之后的有序序列中,具体方法的有序序列中,具体方法: L-Ri.keyRi插入到插入到d1之之前前的有序表中;的有序表中; L-Ri.keyd1.key: L-Ri插入到插入到d1之之后后的有序表中;的有序表中;担薛燎隋冕嫉距蹬惭隧耻分钓匀喳坷助殉蔡跋嚼翌梨天嘶蚤趴逞鸦砸煤延数据结构严蔚敏PPT数据结构严蔚敏PPT关键点关键点:实现时将实现时将

807、向量向量d看成是循环向量,并设两个指看成是循环向量,并设两个指针针first和和final分别指示排序过程中得到的有序序列中的分别指示排序过程中得到的有序序列中的第一个和最后一个记录第一个和最后一个记录。排序示例排序示例设有初始关键字集合设有初始关键字集合49, 38, 65, 13, 97, 27, 76 ,采用,采用2-路插入排序的过程如右图路插入排序的过程如右图10-3所示所示。 在在2-路插入排序中,移动记录的次数约为路插入排序中,移动记录的次数约为n2/8 。但。但当当L-R1是待排序记录中关键字最大或最小的记录时是待排序记录中关键字最大或最小的记录时,2-路插入排序就完全失去了优越

808、性路插入排序就完全失去了优越性。积呵淫截贸苗厦杜番哇曹陷揖鹃盼抓木湃镁甄站毫牙屯匆侥糯棉汾庞钦并数据结构严蔚敏PPT数据结构严蔚敏PPT2776d49firstfirstfirstfirstfinalfinalfinalfinal653897971313图图10-3 2-路插入排序过程路插入排序过程3 表插入排序表插入排序前面的插入排序不可避免地要移动记录前面的插入排序不可避免地要移动记录,若不移动记录若不移动记录就需要改变数据结构。附加就需要改变数据结构。附加n个记录的辅助空间个记录的辅助空间,记录,记录类型修改为:类型修改为:啡固宴泽洱隋舅嫌求省帝慕洋贵吻杜焊等澈陕韧刚盆诲小帚鹰又赠甥模磋

809、数据结构严蔚敏PPT数据结构严蔚敏PPTtypedef struct RecNode KeyType key ;infotype otherinfo ;int *next;RecNode ;初始化初始化:下标值为:下标值为0的分量作为表头结点的分量作为表头结点,关键字取,关键字取为最大值,各分量的指针值为空;为最大值,各分量的指针值为空; 将静态链表中将静态链表中数组下标值为数组下标值为1的分量的分量(结点结点)与表与表头结点构成一个循环链表;头结点构成一个循环链表; i=2 ,将分量,将分量Ri按关键字递减插入到循环链表;按关键字递减插入到循环链表; 增加增加i ,重复,重复,直到全部分量插

810、入到循环链表,直到全部分量插入到循环链表。屑芦寄戮咕窟历惜切茶滤玫咀漠舌沿臼头徊辽戚伦实尔吨俊至悸戏湾医苏数据结构严蔚敏PPT数据结构严蔚敏PPT例:例:设有关键字集合设有关键字集合49, 38, 65, 97, 76, 13, 27, 49 ,采,采用表插入排序的过程如下图用表插入排序的过程如下图10-4所示所示。 0 1 2 3 4 5 6 7 8key域域next域域MAXINT 49 38 65 13 97 27 76 49 1 0 - - - - - - -i=2MAXINT 49 38 65 13 97 27 76 49 2 0 1 - - - - - -i=3MAXINT 49

811、38 65 13 97 27 76 49 2 3 1 0 - - - - -i=4MAXINT 49 38 65 13 97 27 76 49 4 3 1 0 2 - - - -i=5MAXINT 49 38 65 13 97 27 76 49 4 3 1 5 2 0 - - -码稽赣吓曹疙昨漂勒支火桑的隶零歉嘱打詹蛙晓湛滴眶守冀节痕逗杨村彰数据结构严蔚敏PPT数据结构严蔚敏PPT 和直接插入排序相比,不同的是修改和直接插入排序相比,不同的是修改2n次指针值以次指针值以代替移动记录,而代替移动记录,而关键字的比较次数相同关键字的比较次数相同,故时间复杂故时间复杂度为度为O(n2)。 表表插入排

812、序得到一个有序链表,对其可以方便地进插入排序得到一个有序链表,对其可以方便地进行顺序查找,但不能实现随即查找行顺序查找,但不能实现随即查找。根据需要,可以对根据需要,可以对记录进行重排,记录重排详见记录进行重排,记录重排详见P268。i=6MAXINT 49 38 65 13 97 27 76 49 4 3 1 5 6 0 2 - -i=7MAXINT 49 38 65 13 97 27 76 49 4 3 1 7 6 0 2 5 -i=8MAXINT 49 38 65 13 97 27 76 49 4 8 1 7 6 0 2 5 3图图10-4 表插入排序过程表插入排序过程产咬香付辛患越愚霸

813、攫阑粤上踢诀钮仓翰山滁晶谬近甜勘性京珠毖兰滓郁数据结构严蔚敏PPT数据结构严蔚敏PPT10.2.3 希尔排序希尔排序 希尔排序希尔排序(Shell Sort,又称,又称缩小增量法缩小增量法)是一种分是一种分组插入排序方法组插入排序方法。1 排序思想排序思想 先取一个正整数先取一个正整数d1(d1n)作为第一个增量,将全作为第一个增量,将全部部n个记录分成个记录分成d1组,把所有相隔组,把所有相隔d1的记录放在一组的记录放在一组中,即对于每个中,即对于每个k(k=1, 2, d1),Rk, Rd1+k, R2d1+k , 分在同一组中,在各组内进行直接插入分在同一组中,在各组内进行直接插入排序排

814、序。这样一次分组和排序过程称为一趟这样一次分组和排序过程称为一趟希尔排序希尔排序; 取新的增量取新的增量d2d1,重复,重复的分组和排序操作;直的分组和排序操作;直至所取的增量至所取的增量di=1为止,即所有记录放进一个组中排为止,即所有记录放进一个组中排序为止序为止。卸沽扁般缕每哮班像徊袋塌刃但与组焚丢搪嗅东雏溶转逆沫烩巷偶陀砌羞数据结构严蔚敏PPT数据结构严蔚敏PPT2 排序示排序示例例 设有设有10个待排序的记录,关键字分别为个待排序的记录,关键字分别为9, 13, 8, 2, 5, 13, 7, 1, 15, 11,增量序列是,增量序列是5, 3, 1,希尔排序的过程如图,希尔排序的过

815、程如图10-5所示所示。9 7 1 2 5 13 13 8 15 11第一趟排序后第一趟排序后:2 5 1 9 7 13 11 8 15 13第二趟排序后第二趟排序后:1 2 5 7 8 9 11 13 13 15第三趟排序后第三趟排序后:图图10-5 希尔排序过程希尔排序过程9 13 8 2 5 13 7 1 15 1171318初始关键字序列初始关键字序列:第一趟排序过程第一趟排序过程:吝挡析稚辟饼渝禁膜拳伙判欣粕然蹈簧批撵矩惜赤孰猪株把会矩帝救狙需数据结构严蔚敏PPT数据结构严蔚敏PPT3 算法实现算法实现 先给出一趟希尔排序的算法,类似直接插入排序先给出一趟希尔排序的算法,类似直接插入

816、排序。void shell_pass(Sqlist *L, int d) /* 对顺序表对顺序表L进行一趟希尔排序进行一趟希尔排序, 增量为增量为d */ int j, k ;for (j=d+1; jlength; j+) L-R0=L-Rj ; /* 设置监视哨兵设置监视哨兵 */k=j-d ;while (k0<(L-R0.key, L-Rk.key) ) L-Rk+d=L-Rk ; k=k-d ; L-Rk+j=L-R0 ;玛颂放落刷降婉眩挎妙黑仲铲畜六购估阁澄日技押蒋押侠臂炳民雪栏谱绘数据结构严蔚敏PPT数据结构严蔚敏PPT 然后在根据增量数组然后在根据增量数组dk进行希尔排序进

817、行希尔排序。void shell_sort(Sqlist *L, int dk, int t) /* 按增量序列按增量序列dk0 t-1,对顺序表对顺序表L进行希尔排序进行希尔排序 */ int m ;for (m=0; mR1与与L-R2的关键字进行比较的关键字进行比较,若,若为反序为反序( (L-R1的关键字大于的关键字大于L-R2的关键字的关键字) ),则,则交换两个记录交换两个记录;然后比较然后比较L-R2与与L-R3的关键字的关键字,依此类推,直到依此类推,直到L-Rn-1与与L-Rn的关键字比较后的关键字比较后为止为止,称为一趟,称为一趟冒泡排序冒泡排序,L-Rn为关键字最大的为关

818、键字最大的记录记录。岛崩冬闹又档颐壬瘁溯驴脱呵谓篇伯当钩丸杰膝贝哎全豌钳煽领挠崇敬瓣数据结构严蔚敏PPT数据结构严蔚敏PPT 然后进行第二趟然后进行第二趟冒泡排序冒泡排序,对前,对前n-1个记录进行个记录进行同样的操作同样的操作。 一般地,第一般地,第i趟冒泡排序是对趟冒泡排序是对L-R1 n-i+1中的中的记录进行的记录进行的,因此,若待排序的记录有,因此,若待排序的记录有n个个,则要经过,则要经过n-1趟趟冒泡排序才能使所有的记录有序冒泡排序才能使所有的记录有序。2 排序示排序示例例 设有设有9个待排序的记录,关键字分别为个待排序的记录,关键字分别为23, 38, 22, 45, 23,

819、67, 31, 15, 41,冒泡排序的过程如图,冒泡排序的过程如图10-6所示所示。3 算法实现算法实现#define FALSE 0#define TRUE 1摹赤瞪寺渐仪加么修邱啮庙褪蚀速褐备蹋主谆暗匈立凝彬浙僧贺暮蔗挝随数据结构严蔚敏PPT数据结构严蔚敏PPT图图10-6 冒泡排序过程冒泡排序过程23 38 22 45 23 67 31 15 41初始关键字序列初始关键字序列:第一趟排序后第一趟排序后:23 22 38 23 45 31 15 41 67第二趟排序后第二趟排序后:22 23 23 38 31 15 41 45 67第三趟排序后第三趟排序后:22 23 23 31 15

820、38 41 45 67第四趟排序后第四趟排序后:22 23 23 15 31 38 41 45 67第五趟排序后第五趟排序后:22 23 15 23 31 38 41 45 67第六趟排序后第六趟排序后:22 15 23 23 31 38 41 45 67第七趟排序后第七趟排序后:15 22 23 23 31 38 41 45 67辖睛烟贵驶鸭初惧蔗俄手挣转拟谆乓脓挟适底搔绷见觅源通简炒咎冲赵用数据结构严蔚敏PPT数据结构严蔚敏PPTvoid Bubble_Sort(Sqlist *L) int j ,k , flag ;for (j=0; jlength; j+) /* 共有共有n-1趟排序

821、趟排序 */ flag=TRUE ;for (k=1; klength-j; k+) /* 一趟排序一趟排序 */ if (LT(L-Rk+1.key, L-Rk.key ) ) flag=FALSE ; L-R0=L-Rk ; L-Rk=L-Rk+1 ; L-Rk+1=L-R0 ; if (flag=TRUE) break ;尉危车蚕抛焚呢洽洒想扑膏鬃铣救扫哆驱柑赔蹈沛宋碎姚矗为薪揣碧馏但数据结构严蔚敏PPT数据结构严蔚敏PPT故时间复杂度故时间复杂度:T(n)=O(n)空间复杂度:空间复杂度:S(n)=O(1)4 算法分析算法分析时间复杂度时间复杂度 最好情况最好情况(正序正序):比较次数

822、:比较次数:n-1;移动次数:;移动次数:0; 最坏情况最坏情况(逆序逆序):比较次数比较次数:(n-i)=n-1i=1n(n-1)2移动次数移动次数: 3(n-i)=n-1i=13n(n-1)2摘榴鬃席咯式蕴淄寓冀稼姬鸭耶捆汗瓷献憋喂胡舌裂哭秤湃祁侠厦扳娃屠数据结构严蔚敏PPT数据结构严蔚敏PPT10.3.2 快速排序快速排序1 排序思想排序思想 通过一趟排序,将待排序记录分割成独立的两部分,通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,其中一部分记录的关键字均比另一部分记录的关键字小,再分别对这两部分记录进行下一趟排序,以达到整个序再分别对

823、这两部分记录进行下一趟排序,以达到整个序列有序列有序。2 排序过程排序过程 设待排序的记录序列是设待排序的记录序列是Rst ,在记录序列中任取,在记录序列中任取一个记录一个记录(一般取一般取Rs)作为作为参照参照(又称为又称为基准基准或或枢轴枢轴),以以Rs.key为基准重新排列其余的所有记录,方法是:为基准重新排列其余的所有记录,方法是:哑吠嗜漏功甭踪瓤缘掺酿碳伤相效内菇靴谨综乘废鲜警歪幸秋旋唆汛申喊数据结构严蔚敏PPT数据结构严蔚敏PPT 所有关键字比基准小的放所有关键字比基准小的放Rs之前;之前; 所有关键字比基准大的放所有关键字比基准大的放Rs之后之后。 以以Rs.key最后所在位置最

824、后所在位置i作为分界,将序列作为分界,将序列Rst分割成两个子序列,称为一趟快速排序分割成两个子序列,称为一趟快速排序。3 一趟快速排序方法一趟快速排序方法 从序列的两端交替扫描各个记录,将从序列的两端交替扫描各个记录,将关键字小于关键字小于基准关键字的记录基准关键字的记录依次依次放置到序列的前边放置到序列的前边;而将;而将关键字关键字大于基准关键字的记录大于基准关键字的记录从序列的最后端起,依次从序列的最后端起,依次放置到放置到序列的后边序列的后边,直到扫描完所有的记录,直到扫描完所有的记录。 设置指针设置指针low,high,初值为第,初值为第1个和最后一个记录个和最后一个记录的位置。的位

825、置。派掂现坐盖效蚀某耻债湖迸民臼酬敖发至坚颈祟急辨嘉枯础循佑犁幅冈邮数据结构严蔚敏PPT数据结构严蔚敏PPT 设两个变量设两个变量i,j,初始时令,初始时令i=low,j=high,以以Rlow.key作为基准作为基准(将将Rlow保存在保存在R0中中) 。 从从j所指位置向前搜索:将所指位置向前搜索:将R0.key与与Rj.key进行进行比较:比较: 若若R0.keyRj.key :令:令j=j-1,然后继续进行,然后继续进行比较,比较, 直到直到i=j或或R0.keyRj.key为止;为止; 若若R0.keyRj.key :RjRi,腾空腾空Rj的的位置位置, 且令且令i=i+1; 从从i

826、所指位置起向后搜索:将所指位置起向后搜索:将R0.key与与Ri.key进进行比较:行比较: 若若R0.keyRi.key :令:令i=i+1,然后继续进行,然后继续进行比较,比较, 直到直到i=j或或R0.keyRi.key为止;为止;啃愚拱悠荤了笋剧膨彩盛楼慈赵那之镇弦堰勾弯酮怂言渴懒盟蚊柴彭噶则数据结构严蔚敏PPT数据结构严蔚敏PPT 若若R0.keyR0=L-Ri ; /* R0作为临时单元和哨兵作为临时单元和哨兵 */do while (LQ(L-R0.key, L-Rj.key)&(ji) j- ;if (ji) L-Ri=L-Rj ; i+; while (LQ(L-Ri.key

827、, L-R0.key)&(ji) i+ ;if (ji) L-Rj=L-Ri ; j-; while(i!=j) ; /* i=j时退出扫描时退出扫描 */L-Ri=L-R0 ; return(i) ;盔誓桓倾雏聪回守园棚抛犊末狙鸽换领改误哗邑盘拘拘蔑枝忌彭慰殉莹眉数据结构严蔚敏PPT数据结构严蔚敏PPT 快速排序算法实现快速排序算法实现 当进行一趟快速排序后,采用同样方法分别对两个当进行一趟快速排序后,采用同样方法分别对两个子序列快速排序,直到子序列记录个为子序列快速排序,直到子序列记录个为1为止为止。 递归算法递归算法 void quick_Sort(Sqlist *L , int low

828、, int high) int k ;if (lowhigh) k=quick_one_pass(L, low, high);quick_Sort(L, low, k-1);quick_Sort(L, k+1, high); /* 序列分为两部分后分别对每个子序列排序序列分为两部分后分别对每个子序列排序 */曙蚕考眩宜柞层闸舔芭蟹筑呵壬暴搁捶嫌馏闯柞夫霖桅匡芒勃律缨裹饲族数据结构严蔚敏PPT数据结构严蔚敏PPT 非递归算法非递归算法# define MAX_STACK 100void quick_Sort(Sqlist *L , int low, int high) int k , stack

829、MAX_STACK , top=0; do while (lowhigh) k=quick_one_pass(L,low,high); stack+top=high ; stack+top=k+1 ; /* 第二个子序列的上第二个子序列的上,下界分别入栈下界分别入栈 */ high=k-1 ; if (top!=0) low=stacktop- ; high=stacktop- ; 勾翼郧秋皖框暴凄收背炔烃蚊拭莎淖秩确往尔罐环藤筷恼棘倦鼎鸟灿蔚坟数据结构严蔚敏PPT数据结构严蔚敏PPTwhile (top!=0&low1时,用时,用n-1代替代替中的中的n,得到,得到:Tavg(n)=(n-1

830、)C+ Tavg(k) n-2k=02n nTavg(n)-(n-1)Tavg(n-1)=(2n-1)C+2Tavg(n-1) ,即即Tavg(n)=(n+1)/nTavg(n-1)+(2n-1)/nC(n+1)/nTavg(n-1)+2C(n+1)/nn/(n-1)Tavg(n-2)+2C+2C最妈呐夹帆凄镑糖线忙臻吟扼寿绳遏撇完餐单秉售花爬莉棠辩范坝禽蹄掖数据结构严蔚敏PPT数据结构严蔚敏PPT=(n+1)/(n-1)Tavg(n-2)+2(n+1)1/n+1/(n+1)C Tavg(1)+2(n+1)C2n+13141+1n+1n1+ Tavg(n)只有只有1个记录的排序时间是个记录的排

831、序时间是一个常数一个常数, 快速排序的平均时间复杂度是快速排序的平均时间复杂度是:T(n)=O(n2n) 从所需要的附加空间来看,快速排序算法是递归调从所需要的附加空间来看,快速排序算法是递归调用,系统内用堆栈保存递归参数,当每次划分比较均匀用,系统内用堆栈保存递归参数,当每次划分比较均匀时,栈的最大深度为时,栈的最大深度为2n+1 。 快速排序的空间复杂度是:快速排序的空间复杂度是:S(n)=O(2n) 从排序的稳定性来看,快速排序是从排序的稳定性来看,快速排序是不稳定不稳定的。的。诌错辐骄攀秉捶权嚼疯洪秧紫斡游娇刺受奏段徘奄痰撮匝寂莫粘屑羞鹅隶数据结构严蔚敏PPT数据结构严蔚敏PPT10.

832、 4 选择排序选择排序 选择排序选择排序(Selection Sort)的基本思想是:每的基本思想是:每次从当前次从当前待排序的记录待排序的记录中选取关键字最小的中选取关键字最小的记录表,然记录表,然后与后与待排序的记录序列待排序的记录序列中的第中的第一个记录进行交换,直到一个记录进行交换,直到整个记录序列有序为止整个记录序列有序为止。 淬逸驱篡躲柜愿抽傀赡幅小盘嗅酉藉阻芒疚拂泪胳舀徽弗函乏冶玉船度锑数据结构严蔚敏PPT数据结构严蔚敏PPT10.4.1 简单选择排序简单选择排序 简单选择排序简单选择排序(Simple Selection Sort ,又称为,又称为直直接选择排序接选择排序)的基

833、本操作是:通过的基本操作是:通过n-i次关键字间的比较,次关键字间的比较,从从n-i+1个记录中选取关键字最小的记录,然后和第个记录中选取关键字最小的记录,然后和第i个记个记录进行交换,录进行交换,i=1, 2, n-1 。1 排序示例排序示例 例例:设有关键字序列为:设有关键字序列为:7, 4, -2, 19, 13, 6,直接选,直接选择排序的过程如下图择排序的过程如下图10-8所示。所示。垦椰唯丽秀治汀邓饭灭贡砒战聪咖锡钟缆腐犀陕就衬留剔睁阵链柱诽主佩数据结构严蔚敏PPT数据结构严蔚敏PPT图图10-8 直接选择排序的过程直接选择排序的过程初始记录的关键字初始记录的关键字: 7 4 -2

834、 19 13 6第一趟排序第一趟排序:-2 4 7 19 13 6第二趟排序第二趟排序: -2 4 7 19 13 6第三趟排序第三趟排序: -2 4 6 19 13 7第四趟排序第四趟排序: -2 4 6 7 13 19第五趟排序第五趟排序: -2 4 6 7 13 19第六趟排序第六趟排序: -2 4 6 7 13 19铸某顷海侣阁楔言曳五叼暴车亢挚躲雄莫腋践况霖首眶齿蠕鹅仟帐疵魁伯数据结构严蔚敏PPT数据结构严蔚敏PPT2 算法实现算法实现void simple_selection_sort(Sqlist *L) int m, n , k;for (m=1; mlength; m+) k

835、=m ; for (n=m+1; nlength; n+) if ( LT(L-Rn.key, L-Rk.key) ) k=n ;if (k!=m) /* 记录交换记录交换 */ L-R0=L-Rm; L-Rm=L-Rk; L-Rk=L-R0; 费背歧粟诊蕉浪裂严防趟脾鼻度爹徘壹喇挪搅筑暇侣绦百捧绣铃郑懂呛慢数据结构严蔚敏PPT数据结构严蔚敏PPT3 算法分析算法分析 整个算法是二重循环整个算法是二重循环:外循环控制排序的趟数,对:外循环控制排序的趟数,对n个记录进行排序的趟数为个记录进行排序的趟数为n-1趟;内循环控制每一趟的趟;内循环控制每一趟的排序排序。 进行第进行第i趟排序时趟排序时,

836、关键字的比较次数为,关键字的比较次数为n-i,则:,则:比较次数比较次数: (n-i)=n-1i=1n(n-1)2 时间复杂度时间复杂度是是:T(n)=O(n2) 空间复杂度是空间复杂度是:S(n)=O(1) 从排序的稳定性来看从排序的稳定性来看,直接选择排序是直接选择排序是不稳定不稳定的。的。击揩奔宗讹垮史胚剔烙儡痊裔废安歪碾霸渍落若忘姐蹭眯六银寝脊孤次升数据结构严蔚敏PPT数据结构严蔚敏PPT10.4.2 树形选择排序树形选择排序 借助借助“淘汰赛淘汰赛”中的对垒就很容易理解树形选择排中的对垒就很容易理解树形选择排序的思想。序的思想。 首先对首先对n个记录的关键字两两进行比较个记录的关键字

837、两两进行比较,选取,选取 n/2 个较小者;然后这个较小者;然后这 n/2 个较小者个较小者两两进行比较两两进行比较,选取,选取 n/4 个较小者个较小者 如此重复,直到只剩如此重复,直到只剩1个关键字为止个关键字为止。该过程可用一棵有该过程可用一棵有n个叶子结点的完全二叉树表示个叶子结点的完全二叉树表示,如,如图图10-9所示所示。 每个枝结点的关键字都等于其左每个枝结点的关键字都等于其左、右孩子结点中较右孩子结点中较小的关键字小的关键字,根结点的关键字就是最小的关键字根结点的关键字就是最小的关键字。斥阁羹爽封找咱习商靶戊沿嘎逛精拳圭愚帽梦芯委唉吾猫娃颅富役黍嘻唯数据结构严蔚敏PPT数据结构

838、严蔚敏PPT 输出最小关键字后输出最小关键字后,根据,根据关系的可传递性关系的可传递性,欲选取,欲选取次小关键字,只需将叶子结点中的最小关键字改为次小关键字,只需将叶子结点中的最小关键字改为“最最大值大值” ,然后重复上述步骤即可,然后重复上述步骤即可。 含有含有n个叶子结点的完全二叉树的深度为个叶子结点的完全二叉树的深度为 2n +1,则总的时间复杂度为则总的时间复杂度为O(n2n) 。492525372828196519153415251515图图10- “淘汰赛淘汰赛”过程示意图过程示意图畴函同仕钟耸编钳扔够窥诗炮象能恬裴泊腺致篮索玛钩毙憾涛谁蛋痊疥绽数据结构严蔚敏PPT数据结构严蔚敏P

839、PT10.4.3 堆排序堆排序1 堆的定义堆的定义 是是n个元素的序列个元素的序列H=k1, k2 , kn ,满足,满足:kik2i 当当2in时时kik2i+1 当当2i+1n时时或或kik2i 当当2in时时ki k2i+1 当当2i+1n时时其中其中: i=1,2 , , n/2 由堆的定义知,堆是一棵以由堆的定义知,堆是一棵以k1为根的完全二叉树为根的完全二叉树。若对该二叉树的结点进行编号若对该二叉树的结点进行编号(从上到下,从左到右从上到下,从左到右),得到的序列就是将二叉树的结点以得到的序列就是将二叉树的结点以顺序结构存放顺序结构存放,堆的,堆的结构正好和该序列结构完全一致结构正

840、好和该序列结构完全一致。杨用饶峻囚耀虹淑控癣疚掸左驰纂佰铰耻域沁倒娠茸遗尿顽睁至孙酷绘扮数据结构严蔚敏PPT数据结构严蔚敏PPT2 堆的性质堆的性质 堆是一棵采用顺序存储结构的完全二叉树,堆是一棵采用顺序存储结构的完全二叉树, k1是是根结点;根结点; 堆的根结点是关键字序列中的最小堆的根结点是关键字序列中的最小(或最大或最大)值,值,分别称为小分别称为小(或大或大)根堆;根堆; 从根结点到每一叶子结点路径上的元素组成的序从根结点到每一叶子结点路径上的元素组成的序列都是按元素值列都是按元素值(或关键字值或关键字值)非递减非递减(或非递增或非递增)的;的;堆中的任一子树也是堆堆中的任一子树也是堆

841、。 利用堆顶记录的关键字值最小利用堆顶记录的关键字值最小(或最大或最大)的性质,从的性质,从当前待排序的记录中当前待排序的记录中依次选取关键字最小依次选取关键字最小(或最大或最大)的记的记录,就可以实现对数据记录的排序,这种排序方法称为录,就可以实现对数据记录的排序,这种排序方法称为堆排序堆排序。腋西盛已氨营呀缕测传澈松跨芝闽酒呼置轩拖岸烷瘪媚奎荣甚寿评捧岔豹数据结构严蔚敏PPT数据结构严蔚敏PPT3 堆排序思想堆排序思想 对一组待排序的记录,按堆的定义对一组待排序的记录,按堆的定义建立堆建立堆; 将将堆顶记录和最后一个记录交换堆顶记录和最后一个记录交换位置,则前位置,则前n-1个记录是无序的

842、,而最后一个记录是有序的;个记录是无序的,而最后一个记录是有序的; 堆顶记录堆顶记录被交换后,前被交换后,前n-1个记录不再是堆,需个记录不再是堆,需将前将前n-1个待排序记录重新组织成为一个堆,然后将个待排序记录重新组织成为一个堆,然后将堆顶记录和倒数第二个记录交换堆顶记录和倒数第二个记录交换位置,即将整个序位置,即将整个序列中次小关键字值的记录调整列中次小关键字值的记录调整(排除排除)出无序区;出无序区; 重复上述步骤,直到全部记录排好序为止重复上述步骤,直到全部记录排好序为止。 结论结论:排序过程中,若采用排序过程中,若采用小根堆小根堆,排序后得到的是,排序后得到的是非递减序列非递减序列

843、;若采用;若采用大根堆大根堆,排序后得到的是,排序后得到的是非递增序非递增序列列。形寅僵乾舟打碰恳褐恃昏温姑衔里脸份衷霸奔肯伞想策铡上敌啸滔帖哗态数据结构严蔚敏PPT数据结构严蔚敏PPT堆排序的关键堆排序的关键 如何由一个无序序列建成一个堆?如何由一个无序序列建成一个堆? 如何在输出堆顶元素之后,调整剩余元素,使之如何在输出堆顶元素之后,调整剩余元素,使之成为一个新的堆?成为一个新的堆? 4 堆的调整堆的调整筛选筛选 堆的调整思想堆的调整思想 输出堆顶元素之后,以堆中最后一个元素替代之;输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并然后将根结点值与

844、左、右子树的根结点值进行比较,并与其中小者进行交换与其中小者进行交换;重复上述操作,直到是叶子结点;重复上述操作,直到是叶子结点或其关键字值小于等于左、右子树的关键字的值,将得或其关键字值小于等于左、右子树的关键字的值,将得到新的堆。称这个从堆顶至叶子的调整过程为到新的堆。称这个从堆顶至叶子的调整过程为“筛选筛选”,如图,如图10-10所示所示。拂鼠震你哪惦磋剖滑迫幅测仰蜒穴谆弦序床泰鸣骤浚怔蘸时呕崭引堡啊沂数据结构严蔚敏PPT数据结构严蔚敏PPT注意注意:筛选过程中,根结点的左、右子树都是堆,因筛选过程中,根结点的左、右子树都是堆,因此,筛选是从根结点到某个叶子结点的一次调整过程此,筛选是从

845、根结点到某个叶子结点的一次调整过程。图图10-10 堆的筛选过程堆的筛选过程49253728196534182715492537281965342718154927372819653425181549253728196534181527匡渍这姜捞崭旨柬煮侵理涡钦爱滇餐惨驹绷胺照惜距恢史伯两弊澄酌瞬咒数据结构严蔚敏PPT数据结构严蔚敏PPT 堆调整堆调整算法实现算法实现void Heap_adjust(Sqlist *H, int s, int m)/* H-Rsm中记录关键字除中记录关键字除H-Rs.key均满足堆定义均满足堆定义 */* 调整调整H-Rs的位置使之成为的位置使之成为小根堆小根

846、堆 */ int j=s, k=2*j ; /* 计算计算H-Rj的左孩子的位置的左孩子的位置 */H-R0=H-Rj ; /* 临时保存临时保存H-Rj */ for (k=2*j; k=m; k=2*k) if (kRk+1.key, H-Rk.key) k+ ; /* 选择选择左、右孩子中关键字的最小者左、右孩子中关键字的最小者 */if ( LT(H-Rk.key, H-R0.key) ) H-Rj=H-Rk ; j=k ; k=2*j else break ;刻肥臻羡伊锐贬饿簧脉萨遍碾略节喷圈唆酿甚率憨吮牌绩垂苔刺狼窄级桓数据结构严蔚敏PPT数据结构严蔚敏PPTH-Rj=H-R0 ;

847、 5 堆的建立堆的建立 利用筛选算法,可以将任意无序的记录序列建成一利用筛选算法,可以将任意无序的记录序列建成一个堆,个堆,设设R1,R2, ,Rn是待排序的记录序列。是待排序的记录序列。 将二叉树的将二叉树的每棵子树都筛选成为堆每棵子树都筛选成为堆。只有根结点的。只有根结点的树是堆树是堆。第。第 n/2 个结点之后的所有个结点之后的所有结点都没有子树,即结点都没有子树,即以以第第 n/2 个结点之后的个结点之后的结点为根的子树都是堆结点为根的子树都是堆。因此。因此,以这些结点为以这些结点为左、右孩子的结点,其左、右子树都是堆,左、右孩子的结点,其左、右子树都是堆,则则进行一次筛选进行一次筛选

848、就可以成为堆就可以成为堆。同理,只要将这些结点同理,只要将这些结点的直接父结点的直接父结点进行一次筛选进行一次筛选就可以成为堆就可以成为堆。 只需从只需从第第 n/2 个记录到第个记录到第1个记录依次进行筛选就可个记录依次进行筛选就可以建立堆。以建立堆。向糊昂郎献帘竖忱骇构幕痹值漏匝嵌盯豁哉骏梳铆萨型假臃注脱秀标锌暮数据结构严蔚敏PPT数据结构严蔚敏PPT可用下列语句实现可用下列语句实现:for (j=n/2; j=1; j-)Heap_adjust(R, j , n) ;6 堆排序算法实现堆排序算法实现 堆的根结点是关键字最小的记录,输出根结点后,堆的根结点是关键字最小的记录,输出根结点后,

849、是以序列的最后一个记录作为根结点,而原来堆的左、是以序列的最后一个记录作为根结点,而原来堆的左、右子树都是堆,则右子树都是堆,则进行一次筛选进行一次筛选就可以成为堆就可以成为堆。void Heap_Sort(Sqlist *H) int j ;for (j=H-length/2; j0; j-)Heap_adjust(H, j , H-length) ; /* 初始建堆初始建堆 */状败屎棱时琼婿闸俐尉陕汞宏状炮沽洞蹬园啸凡祁励眺微快瞥奢醉倔徊锭数据结构严蔚敏PPT数据结构严蔚敏PPTfor (j=H-length/2; j=1; j-) H-R0=H-R1 ; H-R1=H-Rj ;H-Rj

850、=H-R0 ; /* 堆顶与最后一个交换堆顶与最后一个交换 */Heap_adjust(H, 1, j-1) ; 7 算法分析算法分析 主要过程:初始建堆和重新调整成堆主要过程:初始建堆和重新调整成堆。设记录数为。设记录数为n,所对应的完全二叉树深度为,所对应的完全二叉树深度为h 。 初始建堆初始建堆:每个非叶子结点都要从上到下做:每个非叶子结点都要从上到下做“筛筛选选” 。第。第i层结点数层结点数2i-1,结点下移的最大深度是,结点下移的最大深度是h-i,而每下移一层要比较,而每下移一层要比较2次,则比较次数次,则比较次数C1(n)为:为:崭韶握撤蜂此锨屠波卵故宵菩喀续牺跋颖滑荡援蕊渤易担写

851、娃盐锣焙钉粮数据结构严蔚敏PPT数据结构严蔚敏PPTC1(n) 2 (2i-1(h-i)4(2h-h-1)h-1i=1 h= 2n +1, C1(n)4(n-2n-1) 筛选调整筛选调整:每次筛选要将根结点:每次筛选要将根结点“下沉下沉”到一个到一个合适位置。第合适位置。第i次筛选时次筛选时:堆中元素个:堆中元素个数为数为n-i+1;堆;堆的深度是的深度是 2(n-i+1) +1,则进行,则进行n-1次次“筛选筛选”的比的比较次数较次数C2(n)为为:C2(n) (22(n-i+1)n-1i=1 C2(n)2n2n 堆排序的比较次数的数量级为:堆排序的比较次数的数量级为: T(n)=O(n2n

852、);而附加空间就是交换时所用的临时空间,故空间复;而附加空间就是交换时所用的临时空间,故空间复杂度为:杂度为: S(n)=O(1) 。宅粱恼铲崭醛喧阅身贞粗郝是腾丑斌棠愈沃仓最晃茬氏无攘崔的舀泉焉靴数据结构严蔚敏PPT数据结构严蔚敏PPT10. 5 归并排序归并排序 归并归并(Merging) :是指将两个或两个以上的有序序:是指将两个或两个以上的有序序列合并成一个有序序列。若采用线性表列合并成一个有序序列。若采用线性表(无论是那种存无论是那种存储结构储结构)易于实现,其时间复杂度为易于实现,其时间复杂度为O(m+n) 。 归并思想实例归并思想实例:两堆扑克牌,都两堆扑克牌,都已从小到大排好已

853、从小到大排好序序,要将两堆合并为一堆且要求,要将两堆合并为一堆且要求从小到大排序从小到大排序。 将两堆最上面的抽出将两堆最上面的抽出(设为设为C1,C2)比较大小,将比较大小,将小者置于一边作为新的一堆小者置于一边作为新的一堆(不妨设不妨设C1C2);再从第;再从第一堆中抽出一张继续与一堆中抽出一张继续与C2进行比较,将较小的放置进行比较,将较小的放置在新堆的最下面在新堆的最下面; 重复上述过程,直到某一堆已抽完,重复上述过程,直到某一堆已抽完,然后将剩下然后将剩下一堆中的所有牌转移到新堆中。一堆中的所有牌转移到新堆中。镐渴产权兔蟹魂槛蔚咽衡膝剐赤拯逃倍豪镜另庇擎音敞香桔乔闲绽刚淫甸数据结构严

854、蔚敏PPT数据结构严蔚敏PPT1 排序思想排序思想 初始时,将每个记录看成一个单独的有序序列,初始时,将每个记录看成一个单独的有序序列,则则n个待排序记录就是个待排序记录就是n个长度为个长度为1的有序子序列;的有序子序列; 对所有有序子序列进行两两归并,得到对所有有序子序列进行两两归并,得到 n/2 个长个长度为度为2或或1的有序子序列的有序子序列一趟归并一趟归并; 重复重复 ,直到得到长度为,直到得到长度为n的有序序列为止的有序序列为止。 上述排序过程中,子序列总是上述排序过程中,子序列总是两两归并两两归并,称为,称为2-路路归并排序归并排序。其核心是如何将相邻的两个子序列归并成一其核心是如

855、何将相邻的两个子序列归并成一个子序列个子序列。设。设相邻的两个子序列分别为:相邻的两个子序列分别为:Rk, Rk+1, , Rm和和Rm+1, Rm+2, Rh,将它们归并为一个有序的子序列:,将它们归并为一个有序的子序列:DRl, DRl+1, , DRm, DRm+1, , DRh 晒甫柠朴希冷搐妨愧臃瑟折凌浚绑蜘李池摔祈淀阎拽栗雕雕滨翟钾辱埔碰数据结构严蔚敏PPT数据结构严蔚敏PPT例:例:设有设有9个待排序的记录,关键字分别为个待排序的记录,关键字分别为23, 38, 22, 45, 23, 67, 31, 15, 41,归并排序的过程如图,归并排序的过程如图10-11所示所示。图图1

856、0-11 归并排序过程归并排序过程23 38 22 45 23 67 31 15 41初始关键字初始关键字:23 38 22 45 23 67 15 31 41一趟归并后一趟归并后:22 23 38 45 15 23 31 67 41二趟归并后二趟归并后:15 22 23 23 31 38 45 67 41三趟归并后三趟归并后:15 22 23 23 31 38 41 45 67四趟归并后四趟归并后:部蓟召誓篓愁号擅鞠赢酮毙嗽哗漓观击绵维钟疯葵锌圾指括赡伏混绕甲洲数据结构严蔚敏PPT数据结构严蔚敏PPT归并的算法归并的算法void Merge(RecType R, RecType DR, in

857、t k, int m, int h) int p, q, n ; p=n=k, q=m+1 ;while (p=m)&(q=h) if (LQ(Rp.key, Rq.key) ) /* 比较两个子序列比较两个子序列 */ DRn+=Rp+ ;else DRn+=Rq+ ;while (p=m) /* 将剩余子序列复制到结果序列中将剩余子序列复制到结果序列中 */DRn+=Rp+ ;while (qd:再调用一次上述过程,将:再调用一次上述过程,将一个长度为一个长度为d的子序列和不足的子序列和不足d的子序列进行归并;的子序列进行归并; 剩下的元素个数剩下的元素个数d:将剩下的元素依次复制到:将剩

858、下的元素依次复制到归并后的序列中归并后的序列中。道氟章凭棘哦射糜钩液婪丁盟爷具慢掠穿本虹隧世孩辩顶疵惺器侗孪们州数据结构严蔚敏PPT数据结构严蔚敏PPT 一趟归并排序算法一趟归并排序算法void Merge_pass(RecType R, RecType DR, int d, int n) int j=1 ;while (j+2*d-1)=n) Merge(R, DR, j, j+d-1, j+2*d-1) ;j=j+2*d ; /* 子序列两两归并子序列两两归并 */if (j+d-1n) /* 剩余元素个数超过一个子序列长度剩余元素个数超过一个子序列长度d */Merge(R, DR, j

859、, j+d-1, n) ;else Merge(R, DR, j, n, n) ;/* 剩余子序列复制剩余子序列复制 */视惟桥镍摘勤骑屯阔敖农发壮择诣汗眩叔郭惰挪棱漾娇笼裁擂匙剧磁逻膊数据结构严蔚敏PPT数据结构严蔚敏PPT 归并排序的算法归并排序的算法 开始归并时,每个记录是长度为开始归并时,每个记录是长度为1的有序子序列,对的有序子序列,对这些有序子序列逐趟归并,每一趟归并后有序子序列的这些有序子序列逐趟归并,每一趟归并后有序子序列的长度均扩大一倍;当有序子序列的长度与整个记录序列长度均扩大一倍;当有序子序列的长度与整个记录序列长度相等时,整个记录序列就成为有序序列长度相等时,整个记录序

860、列就成为有序序列。算法是。算法是:void Merge_sort(Sqlist *L, RecType DR) int d=1 ;while(dlength) Merge_pass(L-R, DR, d, L-length) ;Merge_pass(DR, L-R, 2*d, L-length) ;d=4*d ;芽斡发刮址温饰叮屹荔唆也炸鞠嘘或捶已缝度巫辣渝则签尿钩铭轮醛慑时数据结构严蔚敏PPT数据结构严蔚敏PPT3 算法分析算法分析 具有具有n个待排序记录的归并次数是个待排序记录的归并次数是2n,而,而一趟归一趟归并的时间复杂度为并的时间复杂度为O(n),则整个归并排序的,则整个归并排序的时

861、间复杂度时间复杂度无论是最好还是最坏情况均为无论是最好还是最坏情况均为O(n2n)。在排序过程中,在排序过程中,使用了辅助向量使用了辅助向量DR,大小与待排序记录空间相同,则空,大小与待排序记录空间相同,则空间复杂度为间复杂度为O(n)。归并排序是稳定的。归并排序是稳定的。挣谷赊薛窿但绵即断藻荷洒亡壁乏危远过梦棍固栏材蚂浩辕轩孕豢虽榷遗数据结构严蔚敏PPT数据结构严蔚敏PPT10. 6 基数排序基数排序 基数排序基数排序(Radix Sorting) 又称为又称为桶排序桶排序或或数字数字排序排序:按待排序记录的关键字的组成成分:按待排序记录的关键字的组成成分(或或“位位”)进进行排序行排序。

862、基数排序基数排序和前面的各种内部排序方法完全不同,和前面的各种内部排序方法完全不同,不不需要进行关键字的比较和记录的移动。借助于多关键字需要进行关键字的比较和记录的移动。借助于多关键字排序思想实现单逻辑关键字的排序。排序思想实现单逻辑关键字的排序。釜犯量锑湖秒懊颐练届帝更兼贪醒迹趣丙返均朔禹颅镊陆幻应嘿佣这日益数据结构严蔚敏PPT数据结构严蔚敏PPT10.6.1 多关键字排序多关键字排序 设有设有n个记录个记录R1, R2, ,Rn, 每个记录每个记录Ri的关键的关键字是由若干项字是由若干项(数据项数据项)组成,即记录组成,即记录Ri的关键字的关键字Key是是若干项的集合:若干项的集合: Ki

863、1, Ki2, ,Kid(d1) 。 记录记录R1, R2, ,Rn有序的,指的是有序的,指的是 i, j1,n,ij ,若记录的关键字满足:,若记录的关键字满足:Ki1, Ki2, Kid=0; j-) /* 关键字的每位一趟排序关键字的每位一趟排序 */ for (k=0; kkeyj) ; /* 取关键字的第取关键字的第j位位kj */ if (fm=NULL) fm=p ; else em-next=p ; p=p-next ;吊孙研唆举烷赎厚纲乘足慨第冈刨迁紧拳控艇煤铱承西度冗剐科脑硕划借数据结构严蔚敏PPT数据结构严蔚敏PPT head=NULL ; /* 以以head作为头指针进

864、行收集作为头指针进行收集 */ q=head ; /* q作为收集后的尾指针作为收集后的尾指针 */for (k=0; knext=fk ; else head=fk ; q=ek ; /* 完成一趟排序的收集完成一趟排序的收集 */q-next=NULL ; /* 修改收集链尾指针修改收集链尾指针 */稗灵董纶尧帚缨曹呀楷昨扬牡娠酉狭摘忌猖韦帧隙培纳忙魁未为匈葫嫩棠数据结构严蔚敏PPT数据结构严蔚敏PPT4 算法分析算法分析 设有设有n个待排序记录个待排序记录,关键字位数为,关键字位数为d,每位有每位有r种种取值。取值。则排序的趟数是则排序的趟数是d;在每在每一趟中:一趟中: 链表初始化的时

865、间复杂度:链表初始化的时间复杂度:O(r) ; 分配的时间复杂度:分配的时间复杂度:O(n) ; 分配后收集的时间复杂度:分配后收集的时间复杂度:O(r) ; 则链式基数排序的则链式基数排序的时间复杂度为:时间复杂度为: O(d(n+r) 在排序过程中使用的辅助空间是在排序过程中使用的辅助空间是:2r个链表指针个链表指针, n个指针域个指针域空间,则空空间,则空间复杂度为:间复杂度为:O(n+r) 基数排序是稳定的。基数排序是稳定的。冠戊污岂帕饵蹿活坛斤挫卿嫉忍添趴蝗谤遭黍囊燎膘执际附惑喝哎迷癌靛数据结构严蔚敏PPT数据结构严蔚敏PPT10. 7 各种内部排序的比较各种内部排序的比较 各种内部

866、排序按所采用的基本思想各种内部排序按所采用的基本思想(策略策略)可分为:可分为:插入排序插入排序、交换交换排序排序、选择选择排序排序、归并归并排序排序和和基基数数排序排序,它们的基本策略分别是:,它们的基本策略分别是:1 插入排序插入排序:依次将无序序列中的一个依次将无序序列中的一个记录记录,按关,按关键字值的大小插入到已键字值的大小插入到已排好序排好序一个子序列的适当位置,一个子序列的适当位置,直到所有的记录都插入为止直到所有的记录都插入为止。具体的方法有。具体的方法有:直接插入:直接插入、表表插入插入、2-路路插入和插入和shell排序排序。2 交换交换排序排序:对于待排序记录序列中的记录

867、,两两对于待排序记录序列中的记录,两两比较记录的关键字比较记录的关键字,并对反序的两个记录进行交换,直,并对反序的两个记录进行交换,直到整个序列中没有反序的记录偶对为止。到整个序列中没有反序的记录偶对为止。具体的方法有具体的方法有:冒泡排序冒泡排序、快速、快速排序排序。叙算攘裕盼阶勘艘蛊祷堑采蹲择脯仪库浅春三某戊裴别菌稼振蒂细疲困星数据结构严蔚敏PPT数据结构严蔚敏PPT3 选择选择排序排序:不断地从不断地从待排序的记录序列待排序的记录序列中选取关中选取关键字最小的键字最小的记录,放在已记录,放在已排好序的序列排好序的序列的最后的最后,直到所,直到所有记录都被选取为止有记录都被选取为止。具体的

868、方法有。具体的方法有:简单选择排序:简单选择排序、堆堆排序排序。4 归并归并排序排序:利用利用“归并归并”技术不断地对待排序记技术不断地对待排序记录序列中的有序子序列进行合并,直到合并为一个有序录序列中的有序子序列进行合并,直到合并为一个有序序列为止序列为止。5 基数排序基数排序:按待排序记录的关键字的组成成分按待排序记录的关键字的组成成分(“位位”)从低到高从低到高(或从高到低或从高到低)进行进行。每次是按记录关。每次是按记录关键字某一键字某一“位位”的值将所有记录分配到相应的的值将所有记录分配到相应的桶中,再桶中,再按桶的编号依次将记录进行收集,最后得到一个有序序按桶的编号依次将记录进行收

869、集,最后得到一个有序序列列。 各种内部排序方法的性能比较如下表各种内部排序方法的性能比较如下表。洒粪窍葵习吻粮犹脓霉懈掠讫莉套扑柯粉妹后屏嘘冲队京昧朴让罗促骋沟数据结构严蔚敏PPT数据结构严蔚敏PPT方法方法平均时间平均时间最坏所需时间最坏所需时间附加空间附加空间稳定性稳定性直接插入直接插入O(n2)O(n2)O(1)稳定的稳定的Shell排序排序O(n1.3)O(1)不稳定的不稳定的直接选择直接选择O(n2)O(n2)O(1)不稳定的不稳定的堆排序堆排序O(n2n)O(n2n)O(1)不稳定的不稳定的冒泡排序冒泡排序O(n2)O(n2)O(1)稳定的稳定的快速排序快速排序O(n2n)O(n2

870、)O(2n)不稳定的不稳定的归并排序归并排序O(n2n)O(n2n)O(n)稳定的稳定的基数排序基数排序O(d(n+r)O(d(n+r)O(n+r)稳定的稳定的表表7-1 主要内部排序方法的性能主要内部排序方法的性能冉癌补直汹掏拎溜疡能炒羽戊娥罐希池逢抬陋纯批循贞富隙佰灯涟焦超园数据结构严蔚敏PPT数据结构严蔚敏PPT 讲稿中讨论的排序方法是在顺序存储结构上实现的讲稿中讨论的排序方法是在顺序存储结构上实现的,在排序过程中需要移动大量记录。当记录数很多、在排序过程中需要移动大量记录。当记录数很多、时间时间耗费很大耗费很大时时,可以采用静态链表作为存储结构,可以采用静态链表作为存储结构。但有些。但

871、有些排序方法排序方法,若采用静态链表作存储结构,则无法实现表,若采用静态链表作存储结构,则无法实现表排序排序。选取排序方法的主要考虑因素:选取排序方法的主要考虑因素: 待排序的记录数目待排序的记录数目n; 每个记录的大小;每个记录的大小; 关键字的结构及其初始状态;关键字的结构及其初始状态; 是否要求排序的稳定性;是否要求排序的稳定性; 语言工具的特性;语言工具的特性; 存储结构的初始条件和要求;存储结构的初始条件和要求; 时间复杂度时间复杂度、空间复杂度和开发工作的复杂程度空间复杂度和开发工作的复杂程度的平衡点等。的平衡点等。燕筐眠磋科拈索佰幽甥诱巴玛驹痛剥磕弹惟挥盯眼疵绦躲夸铭缓述裤甲辈数

872、据结构严蔚敏PPT数据结构严蔚敏PPT习习 题题 十十 回答下列各题:回答下列各题: 从未排序序列中挑选元素,并将其依次放入到从未排序序列中挑选元素,并将其依次放入到已排序序列中已排序序列中(初始时为空初始时为空)的一端的方法是什么?的一端的方法是什么? 在待排序的元素基本有序的前提下,效率最高在待排序的元素基本有序的前提下,效率最高的排序方法是什么的排序方法是什么? 从未排序序列中依次取出元素与已排序序列从未排序序列中依次取出元素与已排序序列 (初初始时为空始时为空)中的元素进行比较,将其放入已排序序中的元素进行比较,将其放入已排序序列的正确位置方法是什么?列的正确位置方法是什么? 设有设有

873、1000个元素,个元素, 希望采用最快的速度挑选出希望采用最快的速度挑选出其中前其中前10个最大的元素,个最大的元素, 最好的方法是什么最好的方法是什么?恳窘像译唱序膛惊柴浚谢檬绸灭讨棺宗肛灼碳奄绕登呕呕伤贰精傍根劲骋数据结构严蔚敏PPT数据结构严蔚敏PPT 若对关键字序列为若对关键字序列为(54, 37, 93, 25, 17, 68, 58, 41, 76)的的一组记录进行快速排序时,递归调用使用的栈所一组记录进行快速排序时,递归调用使用的栈所能到达的最大深度是多少能到达的最大深度是多少? ?共需递归调用多少次共需递归调用多少次? ?其中第其中第二次递归调用是对哪组记录进行排序二次递归调用

874、是对哪组记录进行排序? ? 在堆排序,快速排序和归并排序中,若只从存储在堆排序,快速排序和归并排序中,若只从存储空间考虑,应选择哪种方法;若只从排序结果的稳定性空间考虑,应选择哪种方法;若只从排序结果的稳定性考虑,应选择哪种方法;若只从平均情况下排序最快考考虑,应选择哪种方法;若只从平均情况下排序最快考虑,应选择哪种方法;虑,应选择哪种方法; 设有关键字序列为设有关键字序列为(14, 17, 53, 35, 9, 32, 68, 41, 76, 23)的的一组记录,请给出用希尔排序法一组记录,请给出用希尔排序法(增量序列是增量序列是5, 3, 1)排序时的每一躺结果。排序时的每一躺结果。 设有

875、关键字序列为设有关键字序列为(14, 17, 53, 35, 9, 37, 68, 21, 46)的的一组记录,请给出冒泡排序法排序时的每一躺结果。一组记录,请给出冒泡排序法排序时的每一躺结果。叶莹蛾摧丢返湿秽即既贞例猾痞歌皂末坯磐磋二姬携流梢砂踢醛絮笑弗疗数据结构严蔚敏PPT数据结构严蔚敏PPT 设有关键字序列为设有关键字序列为(14, 17, 53, 35, 9, 37, 68, 21, 46)的的一组记录,利用快速排序法进行排序时,请给出以第一组记录,利用快速排序法进行排序时,请给出以第一个记录为基准得到的一次划分结果。一个记录为基准得到的一次划分结果。 设关键字序列为设关键字序列为(1

876、4, 17, 53, 35, 9, 37, 68, 21)的的一一组记录,请给出按非递增采用堆排序时的每一躺结果。组记录,请给出按非递增采用堆排序时的每一躺结果。 设关键字序列为设关键字序列为(314, 617, 253, 335, 19, 237, 464, 121, 46, 231, 176, 344)的的一组记录,请给出采用基数排一组记录,请给出采用基数排序时的每一躺结果。序时的每一躺结果。 将哨兵放在将哨兵放在Rn中,被排序的记录存放在中,被排序的记录存放在R1n-1中中,重写直接插入排序算法。,重写直接插入排序算法。 实际中常采用单链表存储数据记录,请写出排序实际中常采用单链表存储数

877、据记录,请写出排序记录的结构的定义并修改。记录的结构的定义并修改。访套悄碉吃壶美冬瘦类磋答檬耻师努契铀硫焦快舶肋认袜恐设蝗候抄貉叮数据结构严蔚敏PPT数据结构严蔚敏PPT第第11章章 文件与外部排序文件与外部排序 在许多实际应用中,特别是数据处理时,都需要在许多实际应用中,特别是数据处理时,都需要长期存储海量数据,这些数据通常以长期存储海量数据,这些数据通常以文件文件的方式组织并的方式组织并存储在外存。如何有效地管理这些数据,从而给使用者存储在外存。如何有效地管理这些数据,从而给使用者提供方便而高效的使用数据的方法称为提供方便而高效的使用数据的方法称为文件管理文件管理。 在实际存取这些海量数据

878、时,为了方便使用,往往在实际存取这些海量数据时,为了方便使用,往往以某种顺序排序后再存储在外存上,这种排序称为以某种顺序排序后再存储在外存上,这种排序称为外部外部排序排序。在排序时由于一次不能将数据文件中的所有数据。在排序时由于一次不能将数据文件中的所有数据同时装入内存中进行,因此就必须研究如何对外存上的同时装入内存中进行,因此就必须研究如何对外存上的数据进行排序的技术。数据进行排序的技术。赚局龄穗集痪锁令掩誉数秒赏分洗最丧痘护玻渍和蔓屠凉贿缺劲勺整努蔼数据结构严蔚敏PPT数据结构严蔚敏PPT11.1 文件的基本概念文件的基本概念1 文件的基本概念文件的基本概念 数据项数据项(Item或或fi

879、eld) :数据文件中最小的基本:数据文件中最小的基本单位单位,反映实体某一方面的特征,反映实体某一方面的特征属性的数据表示属性的数据表示。 记录记录(Record) :一个实体的所有数据项的集合。:一个实体的所有数据项的集合。 用来标识一个记录的数据项集合用来标识一个记录的数据项集合(一个或多个一个或多个)称为关键称为关键字项字项(Key) ,关键字项的值称为关键字,关键字项的值称为关键字;能唯一标识一能唯一标识一个记录的关键字称为个记录的关键字称为主关键字主关键字(Primary Key),其它的关,其它的关键字称为键字称为次关键字次关键字(Secondary Key) 。 通常的记录指的

880、是通常的记录指的是逻辑记录逻辑记录,是从用户角度所看到,是从用户角度所看到的对数据的表示和存取的方式。的对数据的表示和存取的方式。度溯萎碾企皑蹋歼婉狄钥核睡射敞民前讥酣平托存逗悔夯膏滋凤抖仲渺掏数据结构严蔚敏PPT数据结构严蔚敏PPT 文件存储在外存上,通常是以块文件存储在外存上,通常是以块(I/O读写的基本单读写的基本单位,称为位,称为物理记录物理记录)存取。存取。 物理记录和逻辑记录之间的关系是物理记录和逻辑记录之间的关系是: 一个物理记录存放一个逻辑记录;一个物理记录存放一个逻辑记录; 一个物理记录包含多个逻辑记录;一个物理记录包含多个逻辑记录; 多个物理记录存放一个逻辑记录多个物理记录

881、存放一个逻辑记录。 文件文件(File):大量性质相同的数据记录的集合。:大量性质相同的数据记录的集合。文件的所有记录是按某种排列顺序呈现在用户面前文件的所有记录是按某种排列顺序呈现在用户面前,这,这种排列顺序可以是按记录的关键字,也可以是按记录进种排列顺序可以是按记录的关键字,也可以是按记录进入文件的先后等入文件的先后等。则记录之间形成一种线性结构则记录之间形成一种线性结构(逻辑逻辑上的上的),称为文件的,称为文件的逻辑结构逻辑结构;文件在外存上的组织方;文件在外存上的组织方式称为文件的式称为文件的物理结构物理结构。基本的物理结构有基本的物理结构有:顺序结构:顺序结构,链接结构,索引结构链接

882、结构,索引结构 。刊恼毯哭活锨寡蝗遥蚂翌药资婴迭哮宪劲捂育诱勘涕容沼吞锦仍磺歉柯啪数据结构严蔚敏PPT数据结构严蔚敏PPT 文件的分类文件的分类 按记录类型,可分为操作系统文件和数据库文件按记录类型,可分为操作系统文件和数据库文件: 操作系统文件操作系统文件(流式文件流式文件) : 连续的字符序列连续的字符序列(串串)的集合;的集合; 数据库文件数据库文件: 有特定结构有特定结构(所有记录的结构都相所有记录的结构都相同同)的数据记录的集合的数据记录的集合。 按记录长度,可分为定长记录文件和不定长记录按记录长度,可分为定长记录文件和不定长记录文件文件: 定长记录文件定长记录文件:文件中每个记录都

883、有固定的数:文件中每个记录都有固定的数据项组成据项组成,每个数据项的长度都是固定的;,每个数据项的长度都是固定的; 不定长记录文件不定长记录文件:与:与定长记录文件相反定长记录文件相反。瘪荣痘森滴越菱砍夜簇估囚绊吐遁扔抱雕盯眠于今捉簇蹦楷葫斥哄橇偶淄数据结构严蔚敏PPT数据结构严蔚敏PPT2 文件的有关操作文件的有关操作 文件是由大量记录组成的线性表文件是由大量记录组成的线性表,因此,对文件的,因此,对文件的操作主要是针对记录的,通常有操作主要是针对记录的,通常有:记录的检索:记录的检索、插入、插入、删除、修改和排序,其中检索是最基本的操作删除、修改和排序,其中检索是最基本的操作。 检索记录检

884、索记录 根据用户的要求从文件中查找相应的记录。根据用户的要求从文件中查找相应的记录。 查找下一个记录查找下一个记录:找当前记录的下一个逻辑记录;:找当前记录的下一个逻辑记录; 查找第查找第k个记录个记录:给出记录的逻辑序号,根据该序:给出记录的逻辑序号,根据该序号查找相应的记录;号查找相应的记录; 按关键字查找按关键字查找:给出指定的关键字值,查找关键字:给出指定的关键字值,查找关键字值相同或满足条件的记录。对数据库文件,有以下四值相同或满足条件的记录。对数据库文件,有以下四种按关键字查找的方式:种按关键字查找的方式:优好乓别问僳板遭谁奸刮哗兹巧廉蹿深字辩毙秸卷禾艘畜汕执号幢惊遮累数据结构严蔚

885、敏PPT数据结构严蔚敏PPT 简单匹配简单匹配:查找关键字的值与给定的值相等的:查找关键字的值与给定的值相等的记录记录; 区域匹配区域匹配:查找关键字的值在某个区域范围内:查找关键字的值在某个区域范围内的记录的记录; 函数匹配函数匹配:给出关键字的某个函数:给出关键字的某个函数,查找符合查找符合条件的记录条件的记录; 组合条件匹配组合条件匹配:给出用布尔表达式表示的多个:给出用布尔表达式表示的多个条件组合条件组合,查找符合条件的记录。查找符合条件的记录。 插入记录插入记录 将给定的记录插入到文件的指定位置。插入是首先将给定的记录插入到文件的指定位置。插入是首先要确定插入点的位置要确定插入点的位

886、置(检索记录检索记录),然后才能插入,然后才能插入。建装途戍稠拎低延桅日拟缮曝皿岿棋跺冒卵舷广籍巫很斤襟醉篡林劝嘘漂数据结构严蔚敏PPT数据结构严蔚敏PPT 删除记录删除记录 从文件中删除给定的记录。记录的删除有两种情况:从文件中删除给定的记录。记录的删除有两种情况: 在文件中删除第在文件中删除第k个记录个记录; 在文件中删除符合条件的记录。在文件中删除符合条件的记录。 修改记录修改记录 对符合条件的记录对符合条件的记录,更改某些属性值,更改某些属性值。修改时首先。修改时首先要要检索到所要修改的记录,然后才能修改检索到所要修改的记录,然后才能修改。 记录排序记录排序 根据指定的关键字根据指定的

887、关键字,对文件中的记录按关键字值的,对文件中的记录按关键字值的大小以非递减或非递增的方式重新排列大小以非递减或非递增的方式重新排列(或存储或存储)。恒牌总哺滑诫肯数津旁柔图锐王咱怂蛋缨柴舌惟求趴郭咱漾耿耪椎犀瞻睫数据结构严蔚敏PPT数据结构严蔚敏PPT11.2 文件的组织方式文件的组织方式 文件的组织方式文件的组织方式指的是文件的物理结构指的是文件的物理结构。11.2.1 顺序文件顺序文件 记录记录按按其在文件中的其在文件中的逻辑顺序逻辑顺序依次进入存储介质依次进入存储介质。在顺序文件中在顺序文件中,记录的逻辑顺序和存储顺序是一致的,记录的逻辑顺序和存储顺序是一致的。 根据根据记录是否按关键字

888、排序记录是否按关键字排序:可分为排序顺序文:可分为排序顺序文件和一般顺序文件件和一般顺序文件; 根据根据逻辑上相邻逻辑上相邻的记录的的记录的物理位置物理位置关系:可分为关系:可分为连续顺序文件和链接顺序文件。连续顺序文件和链接顺序文件。 顺序文件类似于线性表的顺序存储结构顺序文件类似于线性表的顺序存储结构,比较简单,比较简单,适合于顺序存取的外存介质,但不适合随机处理适合于顺序存取的外存介质,但不适合随机处理。馏傻茸胀柜窝仇位汝缀箱腑壤稠惭挖往赁耍嚼寺团工颅卵陌乏忆恃呛矛楞数据结构严蔚敏PPT数据结构严蔚敏PPT11.2.2 索引文件索引文件 索引技术是组织大型数据库的一种重要技术,索引技术是

889、组织大型数据库的一种重要技术,索引索引是记录和记录存储地址之间的对照表是记录和记录存储地址之间的对照表。索引结构索引结构(称为称为索引文件索引文件)由由索引表索引表和和数据表数据表两部分,如图两部分,如图11-1所示所示。 数据表数据表:存储实际的数据记录;:存储实际的数据记录; 索引表索引表:存储记录的:存储记录的关键字关键字和和记录记录(存储存储)地址地址之之间的对照表间的对照表,每个元素称为一个每个元素称为一个索引项索引项。 如果数据文件中的每一个记录都有一个索引项如果数据文件中的每一个记录都有一个索引项,这,这种索引称为种索引称为稠密索引稠密索引,否则,称为,否则,称为非稠密索引非稠密

890、索引。 对于非稠密索引,通常将文件记录划分为若干块,对于非稠密索引,通常将文件记录划分为若干块,块内块内记录可以记录可以无序无序,但,但块间块间必须必须有序有序。若块内记录是有。若块内记录是有序的序的,称为索引顺序文件,否则称为索引非顺序文件,称为索引顺序文件,否则称为索引非顺序文件。对于对于索引非顺序文件,只需对每一块建立一个索引项索引非顺序文件,只需对每一块建立一个索引项。弹萎阔秦赁壬组幼寅驹爸玲炽装璃颜闸憨嚎塘憎萄律婉娶坑务酥泰层瞪睹数据结构严蔚敏PPT数据结构严蔚敏PPT图图11-1 索引结构的基本形式索引结构的基本形式 索引表索引表数据表数据表关键字关键字 指针指针 263 275

891、386 1046 593 681 386 1046 681 593 263 275关键字关键字 其他域其他域(a) 稠密索引文件稠密索引文件索引表索引表数据表数据表(b) 非稠密索引文件非稠密索引文件 263 386 681关键字关键字 指针指针 386 681 263 275关键字关键字 其他域其他域肖命旗荚埂嫂痒皋赚湃思烯坚颈孩肝温巳甄活损艰官天仪獭渔擞蛊鼠廉欢数据结构严蔚敏PPT数据结构严蔚敏PPT 对于对于稠密索引稠密索引,可以根据,可以根据索引项直接查找到记录的索引项直接查找到记录的位置位置。若在索引表中。若在索引表中采用顺序查找采用顺序查找,查找,查找时间复杂度为时间复杂度为O(n

892、) ;若;若采用折半查找采用折半查找,查找,查找时间复杂度为时间复杂度为O(2n) 。 对于稠密索引对于稠密索引,索引项,索引项数目与数据表中记录数相同数目与数据表中记录数相同,当索引表很大时,检索记录需多次访问外存。当索引表很大时,检索记录需多次访问外存。 对于对于非稠密索引非稠密索引,查找的基本思想是:,查找的基本思想是: 首先根据索引找到记录所在块,再将该块读入到内首先根据索引找到记录所在块,再将该块读入到内存,然后再在块内顺序查找。存,然后再在块内顺序查找。 平均查找长度由两部分组成:块地址的平均查找长平均查找长度由两部分组成:块地址的平均查找长度度Lb,块内记录的平均查找长度,块内记

893、录的平均查找长度Lw,即,即ASLbs=Lb+Lw 若将长度为若将长度为n的文件分为的文件分为b块,每块内有块,每块内有s个记录,则个记录,则b=n/s 。设每块的查找概率为。设每块的查找概率为1/b,块内每个的记录查找,块内每个的记录查找概率为概率为1/b,则采用顺序查找方法时有:,则采用顺序查找方法时有:席较胳潭唁填祝忆终拣淮洽拾对城吭屁拽憾千宋栋膀诺霹则咽兆瓶薛砂瞪数据结构严蔚敏PPT数据结构严蔚敏PPTASLbs=Lb+Lw=(b+1)/2+(s+1)/2=(n/s+s)+1显然,当显然,当s=n1/2时时,ASLbs的值达到最小的值达到最小; 若在索引表中采用折半查找方法时有:若在索

894、引表中采用折半查找方法时有:ASLbs=Lb+Lw= 2(n/s+1)+s/2 如果文件中记录数很庞大,对非稠密索引而言,索如果文件中记录数很庞大,对非稠密索引而言,索引也很大,可以将索引表再分块,建立引也很大,可以将索引表再分块,建立索引的索引索引的索引,形,形成树形结构的多级索引,如后面将要介绍的成树形结构的多级索引,如后面将要介绍的ISAM文件文件和和VSAM文件。文件。急忽彪伶锥淀鄙诅鳃隘靡太肚霹垦劣芥佯溶舵貌迂猾努饯拎谍侦炉屋盒教数据结构严蔚敏PPT数据结构严蔚敏PPT11.2.3 ISAM文件文件 ISAM(Indexed Sequential Access Method,顺序索顺

895、序索引存取方法引存取方法),是专为磁盘存取设计的一种文件组织方,是专为磁盘存取设计的一种文件组织方式,采用静态索引结构,是一种三级索引结构的顺序文式,采用静态索引结构,是一种三级索引结构的顺序文件件。图。图11-2是一个磁盘组的结构图。是一个磁盘组的结构图。磁道磁道扇区扇区柱面柱面图图11-2 一个磁盘组结构形式一个磁盘组结构形式盘面盘面 ISAM文件文件由由基本文基本文件件、磁道索引磁道索引、柱面索引柱面索引和和主索引主索引组成组成。 基本文件基本文件按关键字的按关键字的值顺序存放值顺序存放,首先集中存,首先集中存放在同一柱面上,然后再放在同一柱面上,然后再顺序存放在相邻柱面上顺序存放在相邻

896、柱面上;对于对于同一柱面,则按盘面同一柱面,则按盘面的次序顺序存放的次序顺序存放。馅录钱俘虾式涩肖仪攘查棵悉克乙摸讶厢筛挪烟域驾犊戒像誉浚釜迷捂锤数据结构严蔚敏PPT数据结构严蔚敏PPT 在每个柱面上,还开辟了一个溢出区,存放从该柱在每个柱面上,还开辟了一个溢出区,存放从该柱面的磁道上溢出的记录面的磁道上溢出的记录。同一。同一磁道上溢出的记录通常由磁道上溢出的记录通常由指针相链接指针相链接。 ISAM文件为每个磁道建立一个索引项,相同柱面文件为每个磁道建立一个索引项,相同柱面的磁道索引项组成一个索引表,称为的磁道索引项组成一个索引表,称为磁道索引磁道索引,由基本,由基本索引项和溢出索引项组成,

897、其结构是索引项和溢出索引项组成,其结构是: 基本索引项基本索引项:关键字域存放该磁道上的最大关键关键字域存放该磁道上的最大关键字字;指针域;指针域存放该磁道的首地址存放该磁道的首地址。 关键字关键字 指针指针 关键字关键字 指针指针基本索引项基本索引项溢出索引项溢出索引项相麓江扣尤内右舶缨疮污仇辫略忘联据齿耳撞集滞藐夺崩梳鳃帽芹分蜀姻数据结构严蔚敏PPT数据结构严蔚敏PPT 溢出索引项溢出索引项:是为插入记录设置的。关键字域存:是为插入记录设置的。关键字域存放该磁道上放该磁道上溢出溢出的记录的最大关键字;指针域存放的记录的最大关键字;指针域存放溢溢出出记录链表的头指针。记录链表的头指针。 在磁

898、道索引的基础上,又为文件所占用的柱面建立在磁道索引的基础上,又为文件所占用的柱面建立一个一个柱面索引柱面索引,其结构是,其结构是:关键字关键字 指针指针 关键字域存放该关键字域存放该柱面柱面上的最大关键字上的最大关键字;指针域指向;指针域指向该该柱面的第柱面的第1个个磁道索引项磁道索引项。 当柱面索引很大时,柱面索引本身占用很多磁道,当柱面索引很大时,柱面索引本身占用很多磁道,又可为柱面索引建立一个又可为柱面索引建立一个主索引主索引。则。则ISAM文件的三级文件的三级索引结构如图索引结构如图11-3所示所示。啄悍燎昨橱奄邵礁汝们艰闷钓苍先磐户茅碰馆界肉歹柠圾煮舅鹊择吃绞缔数据结构严蔚敏PPT数

899、据结构严蔚敏PPT磁道索引磁道索引柱面索引柱面索引R7 R13 R23 R76 R31基本区基本区溢出区溢出区柱面柱面C1 R2340 R3760 溢出区溢出区柱面柱面Cn23 3076 23403760 76136 348 768 3760主索引主索引348768 3760图图11-3 ISAM文件结构示意图文件结构示意图棵甲锤题篷苍蛾悍揩吼逻搭禄愤锈荐鳃艰蛆眩腹叫喀箔邱抖督峰何答播语数据结构严蔚敏PPT数据结构严蔚敏PPT1 ISAM文件的检索文件的检索 根据关键字查找时,首先从主索引中查找记录所根据关键字查找时,首先从主索引中查找记录所在的柱面索引块的位置;再从柱面索引块中查找磁道索在的

900、柱面索引块的位置;再从柱面索引块中查找磁道索引块的位置;然后再从磁道索引块中查找出该记录所在引块的位置;然后再从磁道索引块中查找出该记录所在的磁道位置;最后从磁道中顺序查找要检索的记录。的磁道位置;最后从磁道中顺序查找要检索的记录。2 记录的插入记录的插入 首先根据待插入记录的关键字查找到相应位置首先根据待插入记录的关键字查找到相应位置;然然后将该磁道中后将该磁道中插入位置及以后的记录后移插入位置及以后的记录后移一个位置一个位置(若若溢出,将该磁道中最后一个记录存入同一柱面的溢出区,溢出,将该磁道中最后一个记录存入同一柱面的溢出区,并修改磁道索引并修改磁道索引) ;最后将记录插入到相应位置。;

901、最后将记录插入到相应位置。漂粘卵墒焊纱假燎弗锄脓徒呜墨玄职啃址打狮搞主她擂便桑主晃儡馏耙群数据结构严蔚敏PPT数据结构严蔚敏PPT3 记录的删除记录的删除 只需找到要删除的记录,对其只需找到要删除的记录,对其做删除标记做删除标记,不移动,不移动记录记录。当经过多次插入和删除操作后。当经过多次插入和删除操作后,基本区有大量被,基本区有大量被删除的记录,而溢出区也可能有大量记录,则周期性地删除的记录,而溢出区也可能有大量记录,则周期性地整理整理ISAM文件,形成一个新的文件,形成一个新的ISAM文件文件。4 ISAM文件的特点文件的特点 优点优点:节省存储空间:节省存储空间,查找速度快,查找速度快

902、; 缺点缺点:处理删除记录复杂:处理删除记录复杂,多次删除后,多次删除后存储空间的存储空间的利用率和存取效率降低利用率和存取效率降低,需定期整理,需定期整理ISAM文件文件。惶许沙焕傀惋愁呻否搏诀诽竿形岭册斥纱敦梆兰庶诽控宗睡卵幽好劝快迂数据结构严蔚敏PPT数据结构严蔚敏PPT11.2.4 VSAM文件文件 VSAM(Virtual Storage Access Method,虚拟存取,虚拟存取方法方法),也是一种索引顺序文件组织方式,利用,也是一种索引顺序文件组织方式,利用OS的虚的虚拟存储器功能,采用的是基于拟存储器功能,采用的是基于B+树的动态索引结构树的动态索引结构。 文件文件的存取不

903、是以柱面、磁道等物理空间为存取单的存取不是以柱面、磁道等物理空间为存取单位,而是以逻辑空间位,而是以逻辑空间控制区间控制区间(Control Interval)和和控制区域控制区域(Control Range)为存取单位为存取单位。 一个一个VSAM文件由文件由索引集索引集、顺序集顺序集和和数据集数据集组成,组成,如图如图11-4所示所示。 文件的文件的记录都存放在数据集中记录都存放在数据集中,数据集又分成多个,数据集又分成多个控制区间控制区间;VSAM进行进行I/O操作的基本单位是控制区间操作的基本单位是控制区间,由一组连续的存储单元组成,同一文件的控制区间大小由一组连续的存储单元组成,同一

904、文件的控制区间大小相同相同;榨推啡少讯帅旱绘扯秒戴棺懈针逐论咖杯听孔癌级蓄处丑钞吉芒邪蛆灭绳数据结构严蔚敏PPT数据结构严蔚敏PPT 每个控制区间存放一个或多个逻辑记录,记录是按每个控制区间存放一个或多个逻辑记录,记录是按关键字值顺序存放在控制区间的前端,尾端存放记录关键字值顺序存放在控制区间的前端,尾端存放记录的的控制信息和控制区间的控制信息,如图控制信息和控制区间的控制信息,如图11-5所示所示。 控制区间控制区间 69 124 246 22 38 69 198 246 12 20 24 31 386812141720 212 228 246203208212213218228233238

905、246 控制区域控制区域索索引引集集顺序集顺序集B+树树图图11-4 VSAM文件结构示意图文件结构示意图数据集数据集围舜懂矮仰息叁吸刁酞慰技扦颊克嘲戮络吊御饮计纪李累腺涤故闻森阉棠数据结构严蔚敏PPT数据结构严蔚敏PPT 顺序集顺序集是由是由B+树索引结构的叶子结点组成。每个结树索引结构的叶子结点组成。每个结点存放若干个相邻控制区间的索引项,每个索引项存放点存放若干个相邻控制区间的索引项,每个索引项存放一个控制区间中记录的最大关键字值和指向该控制区间一个控制区间中记录的最大关键字值和指向该控制区间的指针。顺序集中的每个结点及与它所对应的全部控制的指针。顺序集中的每个结点及与它所对应的全部控制

906、区间组成一个区间组成一个控制区域控制区域。 顺序集中的结点之间按顺序顺序集中的结点之间按顺序链接链接成一个链表成一个链表,每个,每个结点又在其上层建立索引,并逐层向上按结点又在其上层建立索引,并逐层向上按B+树的形式建树的形式建立多级索引立多级索引。则。则顺序集中的每一个结点就是顺序集中的每一个结点就是B+树的叶子树的叶子结点结点;在顺序集之上的索引部分称为;在顺序集之上的索引部分称为索引集索引集。 在在VSAM文件上既可以按文件上既可以按B+树的方式实现记录的查树的方式实现记录的查找找,又可以利用顺序集索引,又可以利用顺序集索引实现记录实现记录顺序查找顺序查找。未用的未用的自由空间自由空间R

907、n的的控制信息控制信息R1的的控制信息控制信息控制区间的控制区间的控制信息控制信息R1 R2 Rn图图11-5 控制区间的结构控制区间的结构雄苹拧迅卒轨镑转任惰氏傍尝卒鸿雌锅氢袁黄显扰簧琉姥穆见炭芹费哀椎数据结构严蔚敏PPT数据结构严蔚敏PPT VSAM文件中没有溢出区,解决方法是留出空间文件中没有溢出区,解决方法是留出空间: 每个控制区间中留出空间每个控制区间中留出空间; 每个控制区域留出空的控制空间,并在顺序集的每个控制区域留出空的控制空间,并在顺序集的索引中指出索引中指出。1 记录的插入记录的插入 首先根据待插入记录的关键字查找到相应的位置:首先根据待插入记录的关键字查找到相应的位置:

908、若若该控制区间有可用空间该控制区间有可用空间:将关键字:将关键字大于待插入大于待插入记录的关键字的记录全部后移记录的关键字的记录全部后移一个位置,在空出的一个位置,在空出的位置存放待插入记录;位置存放待插入记录; 若若控制区间没有可用空间控制区间没有可用空间:利用同一控制区域的:利用同一控制区域的一个空白控制空间进行区间分裂,将近一半记录移一个空白控制空间进行区间分裂,将近一半记录移到新的控制区间中,并修改顺序集中相应的索引,到新的控制区间中,并修改顺序集中相应的索引,插入新的记录;插入新的记录;曙譬交沸风脂榆蛇钳界规郴父臣躁垮婆吞伊沫健氛百聋籽振潭昨突莹孵乔数据结构严蔚敏PPT数据结构严蔚敏

909、PPT 若若控制区域中没有空白控制空间控制区域中没有空白控制空间:则开辟一个新的:则开辟一个新的控制区域,进行控制区间域分裂和相应的顺序集中的控制区域,进行控制区间域分裂和相应的顺序集中的结点分裂结点分裂。也可按也可按B+树的分裂方法进行树的分裂方法进行。2 记录的删除记录的删除 先找到要删除的记录,然后将同一控制区间中比删先找到要删除的记录,然后将同一控制区间中比删除记录关键字大的所有记录逐个前移,覆盖要删除的记除记录关键字大的所有记录逐个前移,覆盖要删除的记录录。当一个控制区间的记录全部删除后。当一个控制区间的记录全部删除后,需修改顺序集,需修改顺序集中相应的索引项中相应的索引项。3 VS

910、AM文件的特点文件的特点 优点优点 能动态地分配和释放空间;能动态地分配和释放空间;径葡员戏傻婪朴毁协慌岩袄款特氯丈灵烽丙岔外赶戌匠盎互浅祁傅敞麓蔚数据结构严蔚敏PPT数据结构严蔚敏PPT 能保持较高的能保持较高的查询效率,无论是查询原有的还查询效率,无论是查询原有的还是后插入的记录,都有相同的查询速度是后插入的记录,都有相同的查询速度; 能保持较高的能保持较高的存储利用率存储利用率(平均平均75%) ; 永远不需定期整理文件或对文件进行再组织永远不需定期整理文件或对文件进行再组织。 缺点缺点 为保证具有较好的索引结构,在插入或删除时为保证具有较好的索引结构,在插入或删除时索引结构本身也在变化

911、索引结构本身也在变化; 控制信息和索引占用空间较多,因此,控制信息和索引占用空间较多,因此,VSAM文文件通常比较庞大件通常比较庞大。 基于基于B+树的树的VSAM文件通常被作为大型索引顺序文文件通常被作为大型索引顺序文件的标准件的标准。积须叫起澄莎佳呸靡遣吊讯该骑尹驹轧疙赵倚蜕肢破拟耸萨茸材底屈珍撰数据结构严蔚敏PPT数据结构严蔚敏PPT11.2.5 散列文件散列文件 散列文件散列文件(直接存取文件直接存取文件) :利用散列存储方式利用散列存储方式组织的文件组织的文件。类似散列表。类似散列表,即根据文件中记录关键字的,即根据文件中记录关键字的特点,设计一个散列函数和冲突处理方法,将记录散列特

912、点,设计一个散列函数和冲突处理方法,将记录散列到存储介质上到存储介质上。 在散列文件中,磁盘上的记录是成组存放的,若干在散列文件中,磁盘上的记录是成组存放的,若干个记录组成一个存储单位,称为个记录组成一个存储单位,称为桶桶(Bucket),同一个桶同一个桶中的记录都是同义词中的记录都是同义词(关键字的角度关键字的角度) 。 设设一个桶中能存放一个桶中能存放m个记录个记录,当桶中已有当桶中已有m个同义个同义词的记录时词的记录时,要存放第要存放第m+1个同义词就个同义词就“溢出溢出” 。冲突。冲突处理方法一般是处理方法一般是拉链法拉链法。 检索记录时,先根据给定值求出散列桶地址,将基检索记录时,先

913、根据给定值求出散列桶地址,将基穿箍间跳狮落斟薯因渡旧绽燥事煮啤吗资恫葵锑河绰寥澡揣圃歪遏捞猜蛛数据结构严蔚敏PPT数据结构严蔚敏PPT桶的记录读入内存进行顺序查找,若找到关键字等于给桶的记录读入内存进行顺序查找,若找到关键字等于给定值的记录,则查找成功;否则,依次读入各溢出桶中定值的记录,则查找成功;否则,依次读入各溢出桶中的记录继续进行查找。的记录继续进行查找。 在散列文件中删除记录,是对在散列文件中删除记录,是对记录加删除标记记录加删除标记 。散列文件的特点散列文件的特点 优点优点 文件随机存取,记录不需进行排序文件随机存取,记录不需进行排序; 插入、删除方便,存取速度快插入、删除方便,存

914、取速度快; 不需要索引区,不需要索引区,节省节省存储空间存储空间。 缺点缺点 不能进行顺序存取,只能按关键字随机存取不能进行顺序存取,只能按关键字随机存取; 检索方式仅限于简单查询检索方式仅限于简单查询。奶酣统枢貌提放刚糠碌蜗刘淳己硒悦烫斑趁算词桥薛拈损察枣保泵着幽釉数据结构严蔚敏PPT数据结构严蔚敏PPT11.2.6 多关键字文件多关键字文件 数据库文件常常是多关键字文件,多关键字文件的数据库文件常常是多关键字文件,多关键字文件的特点是不仅可以对主关键字进行各种查询,而且可以对特点是不仅可以对主关键字进行各种查询,而且可以对次关键字进行各种查询次关键字进行各种查询。因此。因此,对多关键字文件

915、除了可,对多关键字文件除了可按前面的方法组织主关键字索引外,还需要建立各个次按前面的方法组织主关键字索引外,还需要建立各个次关键字的索引关键字的索引。由于建立。由于建立次关键字的索引的结构不同,次关键字的索引的结构不同,多关键字文件有多重表文件和倒排文件多关键字文件有多重表文件和倒排文件。毫帚吭拢喷淳鹰菠杏趋要慢笼慑炕绣钮葱措楷骏函射谍践嚷宵税狱黄早晒数据结构严蔚敏PPT数据结构严蔚敏PPT1 多重表文件多重表文件 多重表文件多重表文件(Multilist Files)的特点是:记录按的特点是:记录按主关键字的顺序构成一个串联文件主关键字的顺序构成一个串联文件(物理上的物理上的) ,并建立,并

916、建立主关键字索引主关键字索引(称为主索引称为主索引);对每个次关键字都建立次;对每个次关键字都建立次关键字索引关键字索引(称为次索引称为次索引),所有具有同一次关键字值的,所有具有同一次关键字值的记录构成一个链表记录构成一个链表(逻辑上的逻辑上的)。 主索引主索引一般是非稠密索引,其索引项一般有两项:一般是非稠密索引,其索引项一般有两项:主关键字值、头指针。主关键字值、头指针。 次索引次索引一般是稠密索引,其索引项一般有三项:次一般是稠密索引,其索引项一般有三项:次关键字值、头指针、链表长度。关键字值、头指针、链表长度。头指针头指针指向数据文件中指向数据文件中具有该次关键字值的第具有该次关键字

917、值的第1个记录,在数据文件中为各个个记录,在数据文件中为各个次关键字增加一个指针域,指向具有相同次关键字值的次关键字增加一个指针域,指向具有相同次关键字值的下一个记录的地址。下一个记录的地址。张勿照铡低彭呀俱肄朗仕罩均痊摹杠俐阜只辩百附馏阶戎殴酱俏脸摸枕卯数据结构严蔚敏PPT数据结构严蔚敏PPT 对于任何次关键字的查询,都应首先查找对应的索对于任何次关键字的查询,都应首先查找对应的索引,然后顺着相应指针所指的方向查找属于本链表的记引,然后顺着相应指针所指的方向查找属于本链表的记录。录。多重表文件的特点多重表文件的特点 优点优点易于构造和修改、查询方便。易于构造和修改、查询方便。 缺点缺点插入和

918、删除一个记录时,需要修改多个次关键字的插入和删除一个记录时,需要修改多个次关键字的指针指针(在链表中插入或删除记录在链表中插入或删除记录),同时还要修改各,同时还要修改各索引中的有关信息。索引中的有关信息。忽鲤倡沃冗璃馆滴去您满汲梨需膝胁川币挛眯悬赊我弘病眶荚司却亮肌沃数据结构严蔚敏PPT数据结构严蔚敏PPT2 倒排文件倒排文件 倒排文件倒排文件又称逆转表文件。与多重表文件类似,又称逆转表文件。与多重表文件类似,可以处理多关键字查询。其差别是:可以处理多关键字查询。其差别是: 多重表文件:将具有相同关键字值的记录链接在多重表文件:将具有相同关键字值的记录链接在一起,在数据文件中设有与各个关键字

919、对应的指针一起,在数据文件中设有与各个关键字对应的指针域;域; 倒排文件:将具有相同关键字值的记录的地址收倒排文件:将具有相同关键字值的记录的地址收集在一起,并保存到相应的次关键字的索引项中,集在一起,并保存到相应的次关键字的索引项中,在数据文件中不设置对应的指针域,见在数据文件中不设置对应的指针域,见p321。 次索引次索引是次关键字倒排表,倒排表由次关键字值、是次关键字倒排表,倒排表由次关键字值、记录指针记录指针(地址地址),索引中保持次关键字的逻辑顺序。,索引中保持次关键字的逻辑顺序。曳之熔碍啤滴嫁硫芒剃束又夸怨碑缝辅幸谦飞追浇来苞现壹积憎九汪髓城数据结构严蔚敏PPT数据结构严蔚敏PPT

920、倒排表文件的特点倒排表文件的特点 优点优点检索速度快,插入和删除操作比多重表文件简单。检索速度快,插入和删除操作比多重表文件简单。当插入一个记录时,只要将记录存入数据文件,并当插入一个记录时,只要将记录存入数据文件,并将其存储地址加入各倒排表中;删除也很方便。将其存储地址加入各倒排表中;删除也很方便。 缺点缺点倒排表维护比较困难。在同一索引表中,不同关键倒排表维护比较困难。在同一索引表中,不同关键字值的记录数目不同,同一倒排表中的各项长度不字值的记录数目不同,同一倒排表中的各项长度不等。等。欣欢氧幻押锨茸冻厅猛祸牡肤冻窘投恩猫臻大恍拢肺缄冈峰慧吊笑阐酮耙数据结构严蔚敏PPT数据结构严蔚敏PPT

921、11. 3 外部排序外部排序 当对数据记录量巨大的数据文件进行排序时,由于当对数据记录量巨大的数据文件进行排序时,由于受到内存容量的限制,无法将所有数据记录一次全部读受到内存容量的限制,无法将所有数据记录一次全部读入到内存进行。排序过程中需要多次进行内、外存之间入到内存进行。排序过程中需要多次进行内、外存之间的数据交换。的数据交换。利用外存对数据文件进行排序利用外存对数据文件进行排序称为称为外部外部排序排序。胖贯畅壶亿逢廖贬婆猪储衷腺候坍当鸣蜜观谁环疫亮吕泵苛挡姥肉游哑稿数据结构严蔚敏PPT数据结构严蔚敏PPT11.3.1 外部排序方法外部排序方法 外部排序最基本的方法是外部排序最基本的方法是

922、归并归并。这种方法是由两个。这种方法是由两个相对独立的阶段组成:相对独立的阶段组成: 按内存按内存( (缓冲区缓冲区) )的大小,将的大小,将n个记录的数据文件个记录的数据文件分成若干个长度为分成若干个长度为l的段或子文件,依次读入内存并的段或子文件,依次读入内存并选择有效的内部排序方法进行排序;然后将排好序选择有效的内部排序方法进行排序;然后将排好序的有序子文件重新写入到外存。子的有序子文件重新写入到外存。子文件称为文件称为归并段归并段或或顺串顺串。 采用归并的办法对采用归并的办法对归并段归并段进行逐趟归并,使进行逐趟归并,使归并归并段段的长度逐渐增大,直到最后合并成只有一个的长度逐渐增大,

923、直到最后合并成只有一个归并归并段段的文件的文件排好序的文件排好序的文件。垄恍啄六孙朋痘词调蚜坞簿劈霸偷剪杯盖产杰允始室究撬仅乞诌贮症旷竿数据结构严蔚敏PPT数据结构严蔚敏PPT1 外部排序的简单方法外部排序的简单方法 归并排序有多种方法,最简单的就是归并排序有多种方法,最简单的就是2-路归并。路归并。 设有一个设有一个磁盘上的数据文件,共有磁盘上的数据文件,共有100,000个记录个记录(A1, A2, ,A100000),页块长为,页块长为200个记录,供排序个记录,供排序使用的缓冲区可提供容纳使用的缓冲区可提供容纳1000个记录的空间,现要对该个记录的空间,现要对该文件进行排序,排序过程可

924、按如下步骤进行:文件进行排序,排序过程可按如下步骤进行: 第一步第一步:每次将每次将5个页块个页块(1000个记录个记录)由外存读到由外存读到内存,内存, 进行内排序,整个文件共得到进行内排序,整个文件共得到10个初始顺串个初始顺串R1R10 (每一个顺串占每一个顺串占5个页块个页块),然后把它们写回到磁,然后把它们写回到磁盘上去,如图盘上去,如图11-6所示。所示。 第二步第二步:然后两两归并,直到成为一个有序文件然后两两归并,直到成为一个有序文件为止。为止。泡遥炽坎拼谰佃散肉只悠蒋队漏拙梗贡微柿贵伯铰赁某贱泪狰钱尖以夯阜数据结构严蔚敏PPT数据结构严蔚敏PPTR1有序的数据文件有序的数据文

925、件R1R2R3R4R5R6R7R8R9R10R1R2R3R4R5R2R3R1R2图图11-6 外部排序过程示意图外部排序过程示意图制雏佰胶漏告颤萄案危罩辰勤厅冕入诈骏普封拳葛甜忱卓拧谋寂缄颗悦祥数据结构严蔚敏PPT数据结构严蔚敏PPT 由图可知,每趟归并由由图可知,每趟归并由m个归并段得到个归并段得到m/2个个归归并段。并段。2 外排序的时间分析外排序的时间分析 外排序的时间消耗比内排序大得多,原因是:外排序的时间消耗比内排序大得多,原因是: 外排序的数据量外排序的数据量(记录记录)一般很大;一般很大; 外排序涉及到内、外存之间的数据交换操作;外排序涉及到内、外存之间的数据交换操作; 外存的操

926、作速度远远比内存中的操作慢。外存的操作速度远远比内存中的操作慢。外排序的总时间由三部分组成:外排序的总时间由三部分组成:外排序的时间外排序的时间=产生初始归并段的时间产生初始归并段的时间(内排序内排序)mtis +I/O操作的时间操作的时间dtio +内部归并的时间内部归并的时间sutmg虑宵青痔波离椒擎琶隘钝婚稀完缝细臼拷勃谓卡丈我报杠以聚瑞担分毡还数据结构严蔚敏PPT数据结构严蔚敏PPT其中:其中:m:初初始始归归并并段段数数目目;tis:得得到到一一个个归归并并段段的的内内排排序序时间;时间;d:总的读、写次数;:总的读、写次数;tio:一次读、写的时间;:一次读、写的时间;s:归归并并

927、的的趟趟数数;utmg:对对u个个记记录录进进行行一一趟趟内内部部归归并并排序的时间。排序的时间。 一一般般地地,tiotis,tiotmg,tio而而取取决决于于所所用用外外存存,因因此此,影影响响外外排排序序效效率率的的主主要要原原因因是是内内、外外存存之之间间数数据据交交换换(读、写外存读、写外存)。提高效率的主要方法。提高效率的主要方法(途径途径)有:有: 进行多路归并,减少文件归并的趟数;进行多路归并,减少文件归并的趟数; 增加归并段的长度,减少初始归并的数目;增加归并段的长度,减少初始归并的数目; 根据不同归并段的长度,采取最佳归并方案。根据不同归并段的长度,采取最佳归并方案。话刘液松肉唯署案洲圃斩渔杏发猿镜厢地钞给杖者以痘谤燃擎姬衡尘赤那数据结构严蔚敏PPT数据结构严蔚敏PPT

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号