六章树和二叉树.PPT
《六章树和二叉树.PPT》由会员分享,可在线阅读,更多相关《六章树和二叉树.PPT(73页珍藏版)》请在三一办公上搜索。
1、第六章树和二叉树,6.1 树的定义和基本术语6.2 二叉树6.3 遍历二叉树和线索二叉树6.4 树和森林6.5 赫夫曼树及其应用,1.树(Tree):是n(n0)个结点的有限集。在任意一棵非空树中(1)有且只有一个称为根(Root)的结点。(2)其余的结点被分为m(m0)个互不相交的有限集,其中每个集合本身又是一棵树,称为根(Root)结点的子树(Sub_Tree)。,6.1 树的定义和基本术语,6.1.1 基本术语,树的定义本身是递归的。递归定义和递归操作在树和二叉树中应用是比较广泛的,应注意领会递归的实质。,2.树的表示法:有图示法、集合表示法、广义表表示法和缩进表示法,见图6.1。,(A
2、(B(E,F(L),G),C(H,I(M,N),D(J,K)(b)广义表表示法,图4.1 树的几种表示法,3.结点的分类:从计算机的角度来分,可以分为终端结点和非终端结点;以树的特征来分,可以分根结点、分支结点和叶子结点;用族谱的关系来分,可以分为双亲结点和孩子结点、祖先结点和子孙结点、兄弟结点和堂兄弟结点。4.度:分为结点的度和树的度两种。结点的度是指与该结点相连接的孩子结点的数目。树的度是指该棵树中所有结点的度中的最大值。5.深度:树是一种分层结构,根结点作为第一层。结点的层次(或称深度)就是指从根结点开始的层次数。树的深度(或层数)是指该树中所有结点的层次中的最大值。,用图示法表示的二叉
3、树中,边的数目(或称分支数,用e表示)恰好比结点数目(用n表示)少一个,即e=n-1。这是树状结构中最重要的一个结论。,6.有序树与无序树:如果将树中结点的各棵子树看成是从左到右有次序的(即不能互换),则称该树为有序树,否则称为无序树。7有向树与无向树:如果树的每个分支都是从一个结点到另一个结点有方向的,则称该树为有向树,否则称为无向树。8.n元树:树的度为n的有向树。9.位置树:是一棵有向树。如果树中结点的每个孩子结点位置是不能被改变的(改变则不是原树),则称该树为位置树。如某结点可能没有第一个孩子结点,但却可能会有第二个、第三个孩子结点。10.m叉树:是树的度为m的有向位置树,即m元位置树
4、。11.森林:是m(m0)棵互不相交的树的集合。对于树中的每个结点而言,其子树的集合就是森林。因此,森林和树是密切相关的。森林中的树也可以有顺序关系和位置关系。,树状结构也是用于存储数据的,我们也要对其中的数据进行加工处理。总体上,树的基本操作有如下几种:InitTree(T)构造一棵空树T。ClearTree(T)将已经存在的树T清空。TreeEmpty(T)判断树T是否为空树。TreeDepth(T)计算树T的深度。InsertChild(T,p,i,c)插入子树c为树T中p指向结点的第i棵子树。DeleteChild(T,p,i)删除树T中p所指结点的第i棵子树。TraverseTree
5、(T)按某种次序对树T中的所有结点进行访问,每个结点仅访问一次。,6.1.2 树的基本操作,二叉树(Binary Tree)是一种特殊的有向树,也称二元位置树。它的特点是每个结点至多有两棵子树,即二叉树中的每个结点至多有两个孩子结点,且每个孩子结点都有各自的位置关系。或者说,二叉树的子树有左右之分,其次序不能任意颠倒。给二叉树下个更加确切的定义,就是:二叉树或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。,6.2 二叉树,6.2.1 二叉树的定义,可以看出,二叉树的定义是递归的,前面提到的树的定义也是递归的。这说明树状结构在处理数据时很多操作是可以通过递归来
6、完成的。,图6.2 二叉树的五种基本形态,根据二叉树的定义,可以总结出二叉树有如图6.2所示的五种形态:,【例6.1】列举出只有两个结点、三个结点的二叉树的所 有形态,1.只有两个结点的二叉树的形态有两种,如图6.3所示,2.只有三个结点的二叉树的形态有五种,如图6.4所示,6.2.2 二叉树的性质与结论,性质1:在二叉树的第i(i1)层上至多有2i-1个结点。(该性质证明利用归纳法很容易实现,留给读者自己去思考),性质2:深度为k(k1)的二叉树上至多有2k-1个结点。(该性质证明直接利用性质1即可,留给读者自己去思考),性质3:任意一棵二叉树中,叶子结点的数目(用n0表示)总比度为2的结点
7、的数目(用n2表示)多一个,即n0=n2+1。,证明:设结点总数为n,度为1的结点数目为n1,则有 n=n0+n1+n2(6-1)由于二叉树中除根之外的每个结点都带有一个向上的分支,设分支总数为e,则e=n-1(6-2)由于这些分支不是度为1的结点射出的分支,就是度为2的结点射出的分支,则e=1n1+2n2(6-3)由(6-2)式和(6-3)式,得n-1=n1+2n2(6-4)由(6-1)式和(6-4)式,得1=n0-n2 即 n0=n2+1 证毕。,两种特殊形态的二叉树,满二叉树:除叶子结点外的任何结点均有两个孩子结点,且所有的叶子结点都在同一层上的二叉树。特点是每一层上的结点数都是最大的。
8、,完全二叉树:除去最底层结点后的二叉树是一棵满二叉树,且最底层结点均靠左对齐的二叉树。在这里,靠左对齐的含义是左边是满的,即没有空隙再放入任何一个结点。,如图6.5(a)是一棵深度为4的满二叉树,而图6.5(b)是一棵深度为4的完全二叉树。实质上,满二叉树是完全二叉树的一个特例,证明:设具有n个结点的完全二叉树的深度为k,则由性质2可知2k-1-1n2k-1则 2k-1n2k 取以2为底的对数,得 k-1log2nk log2n处于两个连续的整数k-1和k之间 k-1=log2n即 k=log2n+1 证毕。,性质4:具有n个结点的完全二叉树的深度为log2n+1。,性质5:对有n个结点的完全
9、二叉树中的任一结点i(1in),有(1)其双亲结点编号为i/2(1in)。(2)其左孩子结点的编号为2i(1in/2)。(3)其右孩子结点的编号为2i+1(1i(n-1)/2),证明:设树中分支数为e,则根据树的定义可知:e=n-1。若n为偶数,则分支数e为奇数,根据完全二叉树的定义可知,在完全二叉树中仅有一个度为1的结点。同理,若n为奇数时,则分支数e为偶数,所以在完全二叉树中没有度为1的结点。证毕。,性质6:当结点个数n为偶数时,完全二叉树中有且仅有一个度为1的结点;当结点个数n为奇数时,完全二叉树中没有度为1的结点,证明:(1)当n为偶数时,由性质6可知:完全二叉树中有一个度为1的结点,
10、即 n1=1,由性质3可知,n0=n2+1,即 n0=n2+n1(6-5)又结点总数为 n=n0+n1+n2(6-6)由(6-5)和(6-6)式,得 n0=n2+n1=n/2=n/2 即,当n为偶数时,编号大于n/2的结点均为叶子结点。(2)当n为奇数时,由性质6可知:完全二叉树中没有度为1的结点,即n1=0,由性质3可知,n0=n2+1(6-7)又结点总数为 n=n0+n1+n2,即 n=n0+n2(6-8)由(6-7)式和(6-8)式,得n=2n2+1 即 n1+n2=(n-1)/2=n/2 所以,当n为奇数时,编号大于n/2的结点均为叶子结点。,性质7:在完全二叉树中编号大于n/2的结点
11、均为叶子结点。,【例6.2】已知一棵完全二叉树中有234个结点,问(1)树的高度是多少?(2)第7层和第8层上各有多少个结点?(3)树中有多少个叶子结点?多少个度为2的结点?多少个度为1的结点?,注意:一般二叉树的性质可用于完全二叉树;反之,完全二叉树的性质和结论是不能用于一般二叉树中的。,解:(1)由性质4可知该完全二叉树的高度(k)为:k=log2234+1=log227+1=8 即该二叉树的高度为8层。(2)由性质1可知第7层上的结点数为:27-1=26=64(个)。由性质2可知第8层上的结点数为:234-(27-1)=107(个)。(3)由性质7可知树中叶子结点个数为:234-234/
12、2=117(个)。由性质2可知度为2的结点个数为:117-1=116(个)。由性质6可知度为1的结点个数为:1(个)。,6.2.3 二叉树的存储结构6.2.3.1 二叉树的顺序存储结构将二叉树上的结点值按从上至下、从左至右的顺序存储到一个线性结构(常为数组)中,数组中的下标为0的单元可用于存放二叉树中结点的个数或二叉树的深度,虚结点可以用一个特殊的标志来识别。,图6.6,void leveltree(SqBitTree bt)/*按满二叉树输出*/int i=1,j;while(i=bt0)/*按层扫描*/for(j=i;j2*i;j+)/*扫描第i层结点*/if(btj=VirNode)pr
13、intf(*);/*若是虚结点,则输出一个“*”号*/else printf(%d,btj);printf(n);i=2*i;/*跳到下一层*/,【例6.3】按层输出二叉树中的所有结点的值。,void exchangetree(SqBitTree bt)/*该二叉树应添加若干虚结点变为满二叉树*/int k=2,i,j;TelemType t;/*第1层只一个结点,所以从第二层开始进行*/while(k=bt0)for(i=k,j=2*k-1;ij;i+,j-)/*同一层结点值逆置即可完成交换*/t=bti;bti=btj;btj=t;k=2*k;,【例6.4】交换二叉树中所有结点的左右子树。
14、,void searchtree(SqBitTree bt,TElemType x,TElemType*pa,TElemType*lc,TElemType*rc)int i=1,k=1;while(k1)*pa=bti/2;else printf(“该结点为根结点!”);if(2*i=bt0)*lc=bt2*i;else printf(“该结点为叶子结点!”);if(2*i+1=bt0)*rc=bt2*i+1;/*左右孩子可能为虚结点*/break;/*找到,处理之后结束*/else k=2*k;,【例6.5】找出值为x的结点的双亲结点和左右孩子结点的值。,6.2.3.2 二叉树的链式存储结构
15、以链表的形式存储二叉树中的结点及其相互之间的关系,图6.7 二叉树的各种链式存储结构,二叉链表的存储类型说明typedef int TElemType;typedef struct BitNode TElemType data;struct BitNode*lchild,*rchild;BitNode,*BitTree;有了这个类型定义,就可以用它来定义二叉链表根结点的指针变量,如同线性链表中用头指针标识整个链表一样,整个二叉链表就是由这个根结点的指针来识别的。比如:BitTree bt;在此,bt就是指向二叉链表的根结点的指针变量,用以标识整个二叉链表。,性质8:具有n个结点的二叉链表中一定
16、有n+1个空链域。,2.二叉树的基本操作CreateBiTree(bt)建立二叉树;PreOrderTraverse(bt)先序遍历二叉树;InOrderTraverse(bt)中序遍历二叉树;PostOrderTraverse(bt)后序遍历二叉树;SearchBiTree(bt,x,p)查找二叉树值为x的结点,带回该结点的指针p;InsertBiTree(bt,p,x)在p指向的结点位置插入一个值为x的结点;DelBiTree(bt,p)删除p指向的结点;,6.3 遍历二叉树和线索二叉树,6.3.1 遍历二叉树依次访问二叉树中的各个结点,而且每个结点仅被访问一次。,数据元素之间的关系是一种
17、一对多的关系,很难从头至尾一遍扫描完,先序遍历(D L R):访问根结点,按先序遍历左子树,按先序遍历右子树。中序遍历(L D R):按中序遍历左子树,访问根结点,按中序遍历右子树。后序遍历(L R D):按后序遍历左子树,按后序遍历右子树,访问根结点。二叉树为空时,执行空操作,即空二叉树已遍历完。,1.二叉树的遍历过程,实质上在遍历二叉树时,每个结点均经过了三次,由于访问的时机不同,就得到了上述三种遍历算法,如图6.8,其中“”表示空指针。,【例6.6】已知一棵二叉树如图6.9,分别写出其三种遍历顺序。,此三种序列恰为表达式a+b*c-d-e/f的前缀表示(波兰式)、中缀表示和后缀表示(逆波
18、兰式)。,f,f,先序遍历:,中序遍历:,后序遍历:,-,+,a,*,b,-,c,d,/,e,-,+,a,*,b,-,c,d,/,e,+,a,*,b,-,c,d,/,e,f,-,【例6.7】已知一棵二叉树的先序序列和中序序列分别为:KAFGIBEDHJC和AGFKEDBHJIC,试画出这棵二叉树的形状。,分析:先序序列中的第一个一定是(子)树的根结点,而中序序列中左子树遍历完成才会访问这个根结点,所以在中序序列中,排在这个根结点前面的结点一定是其左子树上的结点,排在这个根结点后面的结点一定是其右子树上的结点。如此依次作用于各个子树,就可以画出整个二叉树的树形,而且是惟一的,如图6.10所示。,
19、【例6.8】已知一棵二叉树的后序序列和中序序列分别为FBCGIEJDAH和BFGCHIEADJ,试画出这棵二叉树。,分析:后序序列中的最后一个结点一定是(子)树的根结点,而中序序列中左子树遍历完成才会访问这个根结点,所以在中序序列中,排在这个根结点前面的结点一定是其左子树上的结点,排在这个根结点后面的结点一定是其右子树上的结点。如此依次作用于各个子树,就可以画出整个二叉树的树形,而且是惟一的,如图6.11所示。,【例6.9】已知一棵二叉树的先序序列和后序序列分别为:AB和BA,试画出这棵二叉树的形状。,由先序序列可知A一定是根结点,综合两种序列考虑可知B可能是A的左孩子结点,也可能是A的右孩子
20、结点,所以这棵树的形状是不确定的,如图6.12所示。,性质9:若已知一棵二叉树的先(后)序序列和中序序列,则惟一确定这棵二叉树的形状。该性质的结论根据例6.7和例6.8很容易证实,证明略。,(1)先序遍历二叉树的递归算法void PreOrderTraverse(BitTree bt)if(bt!=NULL)printf(“%d”,bt-data);/*访问根结点*/PreOrderTraverse(bt-lchild);/*遍历左子树*/PreOrderTraverse(bt-rchild);/*遍历右子树*/,2.遍历二叉树的递归算法,(3)后序遍历二叉树的递归算法void PostOrd
21、erTraverse(BitTree bt)if(bt!=NULL)PostOrderTraverse(bt-lchild);PostOrderTraverse(bt-rchild);printf(%d,bt-data);,(2)中序遍历二叉树的递归算法void InOrderTraverse(BitTree bt)if(bt!=NULL)InOrderTraverse(bt-lchild);printf(%d,bt-data);InOrderTraverse(bt-rchild);,3.二叉树的建立算法,因为在含有n个结点的二叉链表中一定有n+1个空指针域,所以在输出数据时一定要给出n+1个
22、空指针值。对于数值型数据一般以“-1”代替空指针,对于字符型数据一般以空格“”代替空指针。,BitTree CreateBiTree(void)BitTree bt;TelemType x;scanf(%d,/*返回根结点的指针*/,若输入如下数据:124-1-1-1357-1-18-1-16-1-1,则建立的二叉树如图6.13所示,其中-1用来安排空指针。若data域为字符型,则输入如下数据:12435786,也可以建立如图4.13所示的二叉树,其中“”表示空格符,用来安排空指针。需要注意的是n个结点的二叉树中一定有n+1个空指针,所以要输入n+1个“-1”或空格“”。,二叉树递归遍历应用举
23、例【例6.10】统计二叉树中叶子结点的个数。int n=0;/*定义一个全局变量用来存放叶子结点的个数*/void leafcount(BitTree bt)if(bt!=NULL)if(bt-lchild=NULL,【例6.11】交换二叉树中所有结点的左右子树。BitTree exchangetree(BitTree bt)BitTree t;if(bt!=NULL)if(bt-lchild!=NULL|bt-rchild!=NULL)/*将访问换成交换指针的语句*/t=bt-lchild;bt-lchild=bt-rchild;bt-rchild=t;bt-lchild=exchanget
24、ree(bt-lchild);bt-rchild=exchangetree(bt-rchild);,【例6.12】求二叉树的高度。int hightree(BitTree bt)int H,H1,H2;if(bt=NULL)H=0;/*树空,则高度为0*/else H1=hightree(bt-lchild);/*否则,分别计算左右子树的高度*/H2=hightree(bt-rchild);H=(H1H2?H1:H2)+1;/*取左右子树高度的最大值再加1(根结点)作为树的高度*/return H;,【例6.13】查找值为x的结点。找到带回该结点的指针,否则带回空指针。int find=0;/
25、*设置查找标记:0表示未找到,1表示找到*/void searchtree(BitTree bt,TElemType x,BitTree*p)if(bt!=NULL,【例6.14】删除值为x的结点,使得其左右子树的安排仍然满足原来的中序遍历序列。,分析:为了保持中序遍历序列不变,对于找到的结点p可以分为四种情况考虑:若结点p为叶子结点,则只需将该结点的双亲结点(f)的左指针或右指针置为空即可;若结点p的左子树为空,则只需将该结点(p)的双亲结点(f)的左指针或右指针指向该结点(p)的右孩子结点即可;若结点p的左子树非空,则只需找到结点p的左子树中最右下的结点s(s的右指针必为空),将该结点(s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 六章树 二叉

链接地址:https://www.31ppt.com/p-5330741.html