第七章二叉树_第1页
第七章二叉树_第2页
第七章二叉树_第3页
第七章二叉树_第4页
第七章二叉树_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第七章 二叉树数据结构与关系数据库数据结构与关系数据库 福 建 江 夏 学 院 FUJIAN JIANGXIA UNIVERSITY应用场景 某公司想通过网络传输一些秘密信息给客户,把这些秘密信某公司想通过网络传输一些秘密信息给客户,把这些秘密信息变成二进制码进行传输,为了节省数据文件在计算机内的息变成二进制码进行传输,为了节省数据文件在计算机内的存储空间和提高信息的传输速度,必须采用一种有效的编码存储空间和提高信息的传输速度,必须采用一种有效的编码方法,编写程序实现之,得到如下所示的输出结果。方法,编写程序实现之,得到如下所示的输出结果。掌握树、森林和二叉树的概念,掌握哈夫曼树的构造及哈弗曼

2、编码,掌握如何把树或森林转化为二叉树,掌握二叉树的基本性质、存储结构、遍历。 教学重点与难点: 二叉树基本运算和存储结构,二叉树的遍历。 教学目的与要求1.二叉树的第k层的结点数最多为多少?2(k-1)2设一棵二叉树的深度为k,则该二叉树中最多有多少个结点?2k-1问题二叉树(二叉树(Binary Tree)是个有限元素的集合,该集合或者为空、或者由一个称为根)是个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成。当集合为空时,称该的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成。当集合为空时,称该二叉树为空二叉树

3、。在二叉树中,一个元素也称作一个结点。二叉树为空二叉树。在二叉树中,一个元素也称作一个结点。二叉树是有序的,即若将其左、右子树颠倒,就成为另一棵不同的二叉树。即使树中结二叉树是有序的,即若将其左、右子树颠倒,就成为另一棵不同的二叉树。即使树中结点只有一棵子树,也要区分它是左子树还是右子树。因此二叉树具有五种基本形态,如图点只有一棵子树,也要区分它是左子树还是右子树。因此二叉树具有五种基本形态,如图7.1 所示。所示。7.1 二叉树的基本概念左子树左子树右子树右子树右子树右子树左子树左子树图图7.1 二叉树的五种基本状态二叉树的五种基本状态(b)(c)(d)(e)满二叉树满二叉树在一棵二叉树中,

4、如果满足:在一棵二叉树中,如果满足:(1)所有分支结点都存在左子树和右子树;()所有分支结点都存在左子树和右子树;(2)所)所有叶子结点都在同一层上有叶子结点都在同一层上,则这样的一棵二叉树称作满二叉树。则这样的一棵二叉树称作满二叉树。如图如图7.2所示,所示,(a)图就是一棵满二叉树,()图就是一棵满二叉树,(b)图则不是满二叉树。)图则不是满二叉树。7.1 二叉树的基本概念ABCDEFGHI123456789ABCDEFGHIJKLMNO123456789101112131415图图7.2(a)一棵满二叉树)一棵满二叉树(b)一棵非满二叉树)一棵非满二叉树完全二叉树完全二叉树一棵深度为一棵

5、深度为k 的有的有n 个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为如果编号为i(1in)的结点与满二叉树中编号为)的结点与满二叉树中编号为i 的结点在二叉树中的位置相同的结点在二叉树中的位置相同,则这棵二,则这棵二叉树称为完全二叉树。完全二叉树的叉树称为完全二叉树。完全二叉树的特点是:叶子结点只能出现在最下层和次下层,且最下特点是:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树。显然,一棵满二叉树必定是

6、一棵完全二叉树,而完全二叉树未必是满二叉树。未必是满二叉树。7.1 二叉树的基本概念ABCDEFGHIJ12345678910图图7.3(a)一棵完全二叉树)一棵完全二叉树ABCDEFG1234678(b)一棵非完全二叉树)一棵非完全二叉树性质性质1 一棵非空二叉树的第一棵非空二叉树的第i 层上最多有层上最多有2i-1 个结点(个结点(i1)。)。性质性质2 一棵深度为一棵深度为k 的二叉树中,最多具有的二叉树中,最多具有2k1 个结点。个结点。性质性质3 对于一棵非空的二叉树,如果叶子结点数为对于一棵非空的二叉树,如果叶子结点数为n0,度数为,度数为2 的结点数为的结点数为n2,则有,则有:

7、n0n21。7.2 二叉树的性质性质性质4 具有具有n 个结点的完全二叉树的深度个结点的完全二叉树的深度k 为为log2n+1。性质性质5 对于具有对于具有n 个结点的完全二叉树,如果按照从上至下和从左到右的顺个结点的完全二叉树,如果按照从上至下和从左到右的顺序对二叉树中的所有结点从序对二叉树中的所有结点从1 开始顺序编号,则对于任意的序号为开始顺序编号,则对于任意的序号为i 的结点,的结点,有:有: (1)如果)如果i1,则序号为,则序号为i 的结点的双亲结点的序号为的结点的双亲结点的序号为i/2(“/”表示整除表示整除);如;如果果i1,则序号为,则序号为i 的结点是根结点,无双亲结点。的

8、结点是根结点,无双亲结点。 (2)如果)如果2in,则序号为,则序号为i 的结点的左孩子结点的序号为的结点的左孩子结点的序号为2i;如果;如果2in,则,则序号为序号为i 的结点无左孩子。的结点无左孩子。 (3)如果)如果2i1n,则序号为,则序号为i 的结点的右孩子结点的序号为的结点的右孩子结点的序号为2i1;如果;如果2i1n,则序号为,则序号为i 的结点无右孩子。的结点无右孩子。7.2 二叉树的性质一、顺序存储结构一、顺序存储结构所谓二叉树的顺序存储,就是用一组所谓二叉树的顺序存储,就是用一组连续的存储单元存放二叉树中的结连续的存储单元存放二叉树中的结点点。一般是按照二叉树结点。一般是按

9、照二叉树结点从上至下、从左到右从上至下、从左到右的顺序存储。的顺序存储。7.3 二叉树的存储一棵完全二叉树一棵完全二叉树图图7.4 完全二叉树的顺序存储示意图完全二叉树的顺序存储示意图一、顺序存储结构一、顺序存储结构7.3 二叉树的存储(b)一棵不完全二叉树)一棵不完全二叉树(c)改造后的完全二叉树)改造后的完全二叉树图图7.5 一般二叉树及其顺序存储示意图一般二叉树及其顺序存储示意图一、顺序存储结构一、顺序存储结构二叉树的顺序存储表示可描述为:二叉树的顺序存储表示可描述为:即将即将bt 定义为含有定义为含有MAXNODE 个个elemtype 类型元素的一类型元素的一维数组。维数组。7.3

10、二叉树的存储#define MAXNODE /*二叉树的最大结点数二叉树的最大结点数*/typedef elemtype SqBiTreeMAXNODE /*0 号单元存放根结点号单元存放根结点*/SqBiTree bt;(1)二叉链表存储)二叉链表存储链表中每个结点由三个域组成,除了数据域外,还有两个指针域,分链表中每个结点由三个域组成,除了数据域外,还有两个指针域,分别用来给出该结点左孩子和右孩子所在的链结点的存储地址。结点的别用来给出该结点左孩子和右孩子所在的链结点的存储地址。结点的存储的结构为:存储的结构为:其中,其中,data 域存放某结点的数据信息;域存放某结点的数据信息;lchi

11、ld 与与rchild 分别存放指向分别存放指向左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值左孩子和右孩子的指针,当左孩子或右孩子不存在时,相应指针域值为空(用符号为空(用符号或或NULL 表示)。表示)。 二、链式存储结构(1)二叉链表存储)二叉链表存储二、链式存储结构(a)带头指针二叉链表(b)带头结点二叉链表(2)三叉链表存储)三叉链表存储每个结点由四个域组成,具体结构为:每个结点由四个域组成,具体结构为:其中,其中,data、lchild 以及以及rchild 三个域的意义同二叉链表结构;三个域的意义同二叉链表结构;parent 域为指向该结点双亲结点的指针。域为指向该

12、结点双亲结点的指针。这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相这种存储结构既便于查找孩子结点,又便于查找双亲结点;但是,相对于二叉链表存储结构而言,它增加了空间开销。对于二叉链表存储结构而言,它增加了空间开销。二、链式存储结构lchilddatarchildparent(2)三叉链表存储)三叉链表存储二、链式存储结构二叉树的二叉链表存储表示可描述为:即将BiTree 定义为指向二叉链表结点结构的指针类型。二、链式存储结构typedef struct BiTNode elemtype data; struct BiTNode *lchild,*rchild; /*左右孩子指针*

13、/BiTNode,*BiTree;注:注:*二叉链表是最常用的二叉树存储方式二叉链表是最常用的二叉树存储方式 知识回顾二叉树的定义二叉树的定义二叉树(二叉树(Binary Tree)是个有限元素的集合,该集合或者为)是个有限元素的集合,该集合或者为空空、或者由一个、或者由一个称为根称为根(root)的元素及两个不相交的、被分别称为的元素及两个不相交的、被分别称为左子树左子树和和右子树右子树的二叉树的二叉树组成。组成。ABCDEFGHI123456789知识回顾二叉树的存储二叉树的存储顺序存储顺序存储二叉链表二叉链表三叉链表三叉链表结构如何定义?结构如何定义?一、二叉树的基本操作一、二叉树的基本

14、操作(1)Initiate(bt)建立一棵空二叉树。(2)Create(x,lbt,rbt)生成一棵以x 为根结点的数据域信息,以二叉树lbt 和rbt为左子树和右子树的二叉树。(3)InsertL(bt,x,parent)将数据域信息为x 的结点插入到二叉树bt 中作为结点parent 的左孩子结点。如果结点parent 原来有左孩子结点,则将结点parent 原来的左孩子结点作为结点x 的左孩子结点。(4)InsertR(bt,x,parent)将数据域信息为x 的结点插入到二叉树bt 中作为结点parent 的右孩子结点。如果结点parent 原来有右孩子结点,则将结点parent 原来

15、的右孩子结点作为结点x 的右孩子结点。(5)DeleteL(bt,parent)在二叉树bt 中删除结点parent 的左子树。(6)DeleteR(bt,parent)在二叉树bt 中删除结点parent 的右子树。(7)Search(bt,x)在二叉树bt 中查找数据元素x。(8)Traverse(bt)按某种方式遍历二叉树bt 的全部结点。7.4 二叉树的基本操作及实现(1)Initiate(bt)初始建立二叉树)初始建立二叉树bt,并使,并使bt 指向头结点。在指向头结点。在二叉树根结点前建立头结点,就如同在单链表前建立的头结点,二叉树根结点前建立头结点,就如同在单链表前建立的头结点,

16、可以方便后边的一些操作实现。可以方便后边的一些操作实现。二、算法实现int Initiate (BiTree *bt)/*初始化建立二叉树初始化建立二叉树*bt 的头结点的头结点*/if(*bt=(BiTNode *)malloc(sizeof(BiTNode)=NULL)return 0;(*bt)-lchild=NULL;(*bt)-rchild=NULL;return 1;/算法算法7.1(2)Create(x,lbt,rbt)建立一棵以)建立一棵以x 为根结点的数据域信息,以二叉为根结点的数据域信息,以二叉树树lbt 和和rbt为左右子树的二叉树。建立成功时返回所建二叉树结点的指针;为

17、左右子树的二叉树。建立成功时返回所建二叉树结点的指针;建立失败时返回空指针。建立失败时返回空指针。二、算法实现BiTree Create(elemtype x,BiTree lbt,BiTree rbt)/*生成一棵以生成一棵以x 为根结点的数据域值以为根结点的数据域值以lbt 和和rbt 为左右子树的二叉树为左右子树的二叉树*/BiTree p;if (p=(BiTNode *)malloc(sizeof(BiTNode)=NULL) return NULL;p-data=x;p-lchild=lbt;p-rchild=rbt;return p;/算法算法7.2二、算法实现BiTree In

18、sertL(BiTree bt,elemtype x,BiTree parent)/*在二叉树在二叉树bt 的结点的结点parent 的左子树插入结点数据元素的左子树插入结点数据元素x*/BiTree p;if (parent=NULL) printf(n 插入出错插入出错);return NULL;if (p=(BiTNode *)malloc(sizeof(BiTNode)=NULL) return NULL;p-data=x;p-lchild=NULL;p-rchild=NULL;if (parent-lchild=NULL) parent-lchild=p;else p-lchild=

19、parent-lchild;parent-lchild=p;return bt;/算法算法7.3 ,右插入功能类同,略。,右插入功能类同,略。二、算法实现BiTree DeleteL(BiTree bt,BiTree parent)/*在二叉树在二叉树bt 中删除结点中删除结点parent 的左子树的左子树*/BiTree p;if (parent=NULL|parent-lchild=NULL) printf(n 删除出错删除出错);return NULL;p=parent-lchild;parent-lchild=NULL;free(p); /*当当p 为非叶子结点时为非叶子结点时,这样删

20、除仅释放了所删子树根结点的空间这样删除仅释放了所删子树根结点的空间,*/*若要删除子树分支中的结点若要删除子树分支中的结点,需用后面介绍的遍历操作来实现。需用后面介绍的遍历操作来实现。*/return bt;/算法算法7.4二叉树的遍历二叉树的遍历什么是遍历?什么是遍历?按照某一顺序,访问数据结构中的按照某一顺序,访问数据结构中的所有结点所有结点,使每个,使每个结点都被结点都被访问一次访问一次,而且,而且只访问一次只访问一次。7.5 二叉树的遍历方法及递归实现也叫也叫“周游周游”二叉树的遍历二叉树的遍历为什么要遍历?为什么要遍历?它是插入、删除、修改、查找和排序运算的前提,是它是插入、删除、修

21、改、查找和排序运算的前提,是二叉树一切运算的基础。二叉树一切运算的基础。7.5 二叉树的遍历方法及递归实现“遍历遍历”曾经很简单曾经很简单7.5 二叉树的遍历方法及递归实现a1a2.ai-1aiai+1.an. a1 a2 an .H“遍历遍历”也可以很复杂也可以很复杂7.5 二叉树的遍历方法及递归实现V0V1V2V4V3V5V7V8V6历史上的历史上的“遍历遍历”问题问题-柯尼斯堡七桥问题柯尼斯堡七桥问题7.5 二叉树的遍历方法及递归实现7.5 二叉树的遍历方法及递归实现历史上的历史上的“遍历遍历”问题问题-柯尼斯堡七桥问题柯尼斯堡七桥问题7.5 二叉树的遍历方法及递归实现图论和拓扑学均由此

22、问题发展而来图论和拓扑学均由此问题发展而来7.5 二叉树的遍历方法及递归实现图论和拓扑学均由此问题发展而来图论和拓扑学均由此问题发展而来计算机网络拓扑计算机网络拓扑怎样遍历一棵二叉树怎样遍历一棵二叉树-规定一个顺序规定一个顺序根据定义:非空二叉树由根据定义:非空二叉树由根根、左子树左子树、右子树构成右子树构成只需要按顺序进行以下三个操作:只需要按顺序进行以下三个操作:访问根节点(访问根节点(D)遍历左子树(遍历左子树(L)遍历右子树(遍历右子树(R)7.5 二叉树的遍历方法及递归实现ABCDE怎样遍历一棵二叉树怎样遍历一棵二叉树-规定一个顺序规定一个顺序D、L、R的组合定义了几种可能的遍历方案

23、呢?的组合定义了几种可能的遍历方案呢?LDR、LRD、DLR、DRL、RLD、RDL若限定先左后右,则有三种实现方案:若限定先左后右,则有三种实现方案:7.5 二叉树的遍历方法及递归实现DLRLDRLRD 先先序遍历序遍历 中中序遍历序遍历 后后序遍历序遍历怎样遍历一棵二叉树怎样遍历一棵二叉树-规定一个顺序规定一个顺序7.5 二叉树的遍历方法及递归实现DLRLDRLRD 先先序遍历序遍历 中中序遍历序遍历 后后序遍历序遍历三种方式的步骤是什么三种方式的步骤是什么?(1)访问根结点;)访问根结点;(2)先序遍历根结点的左子树;)先序遍历根结点的左子树;(3)先序遍历根结点的右子树。)先序遍历根结

24、点的右子树。(1)中序遍历根结点的左子树;)中序遍历根结点的左子树;(2)访问根结点;)访问根结点;(3)中序遍历根结点的右子树。)中序遍历根结点的右子树。(1)后序遍历根结点的左子树;)后序遍历根结点的左子树;(2)后序遍历根结点的右子树。)后序遍历根结点的右子树。(3)访问根结点;)访问根结点;例例7.5.1 7.5 二叉树的遍历方法及递归实现先序遍历:先序遍历:根节点根节点左子树左子树右子树右子树ABCDEAB D E E例例7.5.1 7.5 二叉树的遍历方法及递归实现中序遍历:中序遍历:根节点根节点左子树左子树右子树右子树ABCDEAD B E C例例7.5.1 7.5 二叉树的遍历

25、方法及递归实现后序遍历:后序遍历:根节点根节点左子树左子树右子树右子树ABCDEAD E B C例例7.5.2 7.5 二叉树的遍历方法及递归实现中序遍历、先序遍中序遍历、先序遍历、后序遍历分别历、后序遍历分别是什么样的序列?是什么样的序列?a + b * c - d - e / f- + a * b - c d / e fa b c d - * + e f / -先序遍历二叉树的递归算法如下:先序遍历二叉树的递归算法如下:7.5 二叉树的遍历方法及递归实现void PreOrder(BiTree bt)/*先序遍历二叉树先序遍历二叉树bt*/if (bt=NULL) return; /*递归

26、调用的结束条件递归调用的结束条件*/Visit(bt); /*访问结点的数据域访问结点的数据域*/PreOrder(bt-lchild); /*先序递归遍历先序递归遍历bt 的左子树的左子树*/PreOrder(bt-rchild); /*先序递归遍历先序递归遍历bt 的右子树的右子树*/中序遍历二叉树的递归算法如下:中序遍历二叉树的递归算法如下:7.5 二叉树的遍历方法及递归实现void InOrder(BiTree bt)/*中序遍历二叉树中序遍历二叉树bt*/if (bt=NULL) return; /*递归调用的结束条件递归调用的结束条件*/InOrder(bt-lchild); /*

27、中序递归遍历中序递归遍历bt 的左子树的左子树*/Visit(bt); /*访问结点的数据域访问结点的数据域*/InOrder(bt-rchild); /*中序递归遍历中序递归遍历bt 的右子树的右子树*/中序遍历二叉树的递归算法如下:中序遍历二叉树的递归算法如下:7.5 二叉树的遍历方法及递归实现void PostOrder(BiTree bt)/*后序遍历二叉树后序遍历二叉树bt*/if (bt=NULL) return; /*递归调用的结束条件递归调用的结束条件*/PostOrder(bt-lchild); /*后序递归遍历后序递归遍历bt 的左子树的左子树*/PostOrder(bt-

28、rchild); /*后序递归遍历后序递归遍历bt 的右子树的右子树*/Visit(bt); /*访问结点的数据域访问结点的数据域*/7.5 二叉树的遍历方法及递归实现int main(void) BiTree bt,lt,rt;lt=Create(E,NULL,NULL);rt=Create(F,NULL,NULL);rt=Create(C,lt,rt); lt=Create(G,NULL,NULL);lt=Create(D,NULL,lt);lt=Create(B,lt,NULL);bt=Create(A,lt,rt); printf(先序遍历:先序遍历:); PreOrder(bt);p

29、rintf(n);printf(中序遍历:中序遍历:); InOrder(bt);printf(n);printf(后序遍历:后序遍历:); PostOrder(bt);printf(n);return 0;层次遍历层次遍历所谓二叉树的层次遍历,是指从二叉树的第一层(根所谓二叉树的层次遍历,是指从二叉树的第一层(根结点)开始,结点)开始,从上至下从上至下逐层遍历逐层遍历,在,在同一层中同一层中,则按,则按从左从左到右到右的顺序对结点的顺序对结点逐个访问逐个访问。7.5 二叉树的遍历方法及递归实现ABCDEAB CD E层次遍历层次遍历-算法实现思路算法实现思路 可设置一个队列结构,遍历从二叉树

30、的根结点开始,首先将根可设置一个队列结构,遍历从二叉树的根结点开始,首先将根结点指针入队列,然后从对头取出一个元素,每取一个元素,执行结点指针入队列,然后从对头取出一个元素,每取一个元素,执行下面两个操作:下面两个操作:(1)访问该元素所指结点;)访问该元素所指结点;(2)若该元素所指结点的左、右孩子结点非空,则将该元素)若该元素所指结点的左、右孩子结点非空,则将该元素所指结点的左孩子指针和右孩子指针顺序入队。所指结点的左孩子指针和右孩子指针顺序入队。7.5 二叉树的遍历方法及递归实现a1 a2 a3 a4 a5入队入队出队出队层次遍历层次遍历-算法实现算法实现7.5 二叉树的遍历方法及递归实现void LevelOrder(BiTree bt) BiTree queueMAXSIZENODE; int front,rear; if(bt=NULL) return; front=-1; rear=0; queuerear=bt; 层次遍历层次遍历-算法实现算法实现7.5 二叉树的遍历方法及递归实现 while(front!=rear) front+; Visit(queuefront); if(queuefront-l

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论