1 / 107

第6章 树和二叉树

第6章 树和二叉树. 6.1 树的概念与定义  6.2 二叉树 6.3 二叉树的遍历与线索化 6.4 树、森林和二叉树的关系 6.5 哈夫曼树及其应用. 图6.1 树的图示方法. 6.1 树的概念与定义. 树是 n(n≥0) 个结点的有限集合 T。 当 n=0 时,称为空树;当 n>0 时, 该集合满足如下条件:  (1) 其中必有一个称为根( root) 的特定结点,它没有直接前驱,但有零个或多个直接后继。 

radwan
Download Presentation

第6章 树和二叉树

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第6章 树和二叉树 6.1 树的概念与定义 6.2 二叉树 6.3 二叉树的遍历与线索化 6.4 树、森林和二叉树的关系 6.5 哈夫曼树及其应用

  2. 图6.1 树的图示方法

  3. 6.1 树的概念与定义 树是n(n≥0)个结点的有限集合T。当n=0时,称为空树;当n>0时, 该集合满足如下条件:  (1) 其中必有一个称为根(root)的特定结点,它没有直接前驱,但有零个或多个直接后继。  (2) 其余n-1个结点可以划分成m(m≥0)个互不相交的有限集T1,T2,T3,…,Tm,其中Ti又是一棵树,称为根root的子树。 每棵子树的根结点有且仅有一个直接前驱,但有零个或多个直接后继。

  4. 树的相关概念 结点、 结点的度、 叶子、 分支结点、 孩子、兄弟、 祖先、子孙、结点的层次、堂兄弟、树的度、树的高度(深度)、有序树、森林等

  5. A B C D E F G H I J 例1、对于下图所示的树,回答以下问题。 根: 叶子: 内部结点: A—J的度分别是: 树的度是: A的孩子: B的孩子: B的双亲: I的双亲: A C、E、G、H、I、J B、D、F 3、2、0、2、0、2、0、0、0、0 3 B、C、D E、F 树T A F

  6. A B C D E F G H I J 例1、对于下图所示的树,回答以下问题。 互为兄弟的结点: F和G互为: A的子孙: B的子孙: I的祖先: H的祖先: B、C、D互为兄弟 E、F互为兄弟 G、H互为兄弟 I、J互为兄弟 堂兄弟 B--J E、F、I、J A、B、F 树T A、D

  7. A B C D E F G H I J 例1、对于下图所示的树,回答以下问题。 层为1的结点: 层为2的结点: 层为3的结点: 层为4的结点: 树的深度: A B、C、D E、F、G、H I、J 4 树T

  8. ADT Tree{ 数据对象D:一个集合,该集合中的所有元素具有相同的特性。 数据关系R: 若D为空集,则为空树。 若D中仅含有一个数据元素,则R为空集,否则R={H},H是如下的二元关系: (1) 在D中存在唯一的称为根的数据元素root, 它在关系H下没有前驱。 (2) 除root以外, D中每个结点在关系H下都有且仅有一个前驱。

  9. 基本操作:  (1) InitTree(&T): 将T初始化为一棵空树。  (2) DestoryTree(&T): 销毁树T。  (3) CreateTree(&T): 创建树T。  (4) TreeEmpty(T): 若T为空, 则返回TRUE, 否则返回FALSE。  (5) Root(T): 返回树Tree的根。  (6) Parent(T, cur_e): 树T存在, cur_e是T中的某个结点。 若cur_e 为非根结点,则返回它的双亲, 否则返回“空”。 (7) LeftChild(T, cur_e ): 树T存在, cur_e是T中的某个结点。若cur_e为非叶子结点,则返回它的第一个孩子结点, 否则返回“空”。

  10. RightSibling(T,cur_e): 树T存在,cur_e是T中的某个结点。若cur_e 有右兄弟,则返回它的右兄弟, 否则返回“空”. • InsertChild(&T, &p,i, c):树T存在,p指向T中某个结点,1≤i≤d+1,d为p所指向结点的度,非空树c与T不相交。插入c为T中p所指向结点的第i棵子树。  (10) DeleteChild(&T,&p,i): 树T存在, p指向T中某个结点, 1≤i≤d,d为p所指向结点的度。 删除T中p所指向结点的第i棵子树。 (11) TraverseTree(T,Visit()): 树T存在,Visit()是对结点操作的应用函数。按照某种次序对树T的每个结点调用Visit()函数访问一次且最多一次。若Visit()失败, 则操作失败。}

  11. 6.2 二 叉 树 • 6.2.1 二叉树的定义与基本操作 定义:我们把满足以下两个条件的树形结构叫做二叉树(Binary Tree):  (1) 每个结点的度都不大于2;  (2) 每个结点的孩子结点次序不能任意颠倒。 

  12. 二叉树的抽象数据类型 • ADT BinaryTree{数据对象D:D是具有相同特性的数据元素的集合数据关系R:若D=Φ,则R=φ,称二叉树为空二叉树,否则有 有root,左子树DL,右子树Dr基本操作:

  13. 二叉树的五种基本形态 图6.2给出了二叉树的五种基本形态。

  14. 6.2.2 二叉树的性质 • 性质1: 在二叉树的第i层上至多有2i-1个结点(i≥1)。 证明: 用数学归纳法。  归纳基础:当i=1时,整个二叉树只有一根结点,此时2i-1=20=1,结论成立。 归纳假设:假设i=k时结论成立,即第k层上结点总数最多为2k-1个。 现证明当i=k+1时, 结论成立:  因为二叉树中每个结点的度最大为2,则第k+1层的结点总数最多为第k层上结点最大数的2倍,即2×2k-1=2(k+1)-1,故结论成立。

  15. 性质2: 深度为k的二叉树至多有2k-1个结点(k≥1)。 证明:因为深度为k的二叉树,其结点总数的最大值是将二叉树每层上结点的最大值相加,所以深度为k的二叉树的结点总数至多为 故结论成立。

  16. 性质3: 对任意一棵二叉树T,若终端结点数为n0,而其度数为2的结点数为n2,则n0=n2+1。 证明:设二叉树中结点总数为n, n1为二叉树中度为1的结点总数。因为二叉树中所有结点的度小于等于2,所以有 n=n0+n1+n2 (1) 设二叉树中分支数目为B, 因为除根结点外, 每个结点均对应一个进入它的分支,所以有n=B+1

  17. 又因为二叉树中的分支都是由度为1和度为2的结点发出, 所以分支数目为 B=n1+2n2 整理上述两式可得到 n=B+1=n1+2n2+1 (2) 将式(1)代入上式,得出n0+n1+n2=n1+2n2+1,整理后得n0=n2+1,故结论成立。

  18. 满二叉树: 深度为k且有2k-1个结点的二叉树称为满二叉树。 深度为k,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。 图6.3 满二叉树与完全二叉树

  19. 性质4:具有n个结点的完全二叉树的深度为 证明:假设n个结点的完全二叉树的深度为k,根据性质2可知,k-1层满二叉树的结点总数为 n1=2k-1-1 k层满二叉树的结点总数为 n2=2k-1 显然有n1<n≤n2,进一步可以推出n1+1≤n<n2+1。 将n1=2k-1-1和n2=2k-1代入上式,可得2k-1≤n<2k, 即k-1≤log2n<k。  因为k是整数,所以k-1= ,k= , 故结论成立。 

  20. 性质5: 如果对一颗有n个结点的完全二叉树(其深度为 )的结点按层序(从第1层到第 层,每层从左到右),则对任一结点i(1≤ i≤ n)有:  (1)如果i=1,则结点I是二叉树的根,无双亲;如果i>1,则其双亲PARENT(i)是结点 。  (2) 如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i。  (3) 如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1。 

  21. 可以用归纳法证明其中的(2)和(3):  当i=1时,由完全二叉树的定义知,满足性质5:中的(2)和(3)。 1 2 3 … 4

  22. 当i>1时:情况① 第j层第1个结点,i=2j-1 i … 第j+1层第1个结点,编号为 2j=2(2j-1)=2i 第j层 … 第j+1层 2i 2i+1

  23. 当i>1时:情况② i … i+1 … … 2i 2i+1 2i+2 2i+3 …

  24. i i+1 … 2i 2i+1 … 2i+2 2i+3 故(2)和(3)得证。

  25. 由(2)和(3)我们可以很容易证明(1)。证毕。

  26. 6.2.3 二叉树的存储结构 二叉树的结构是非线性的, 每一结点最多可有两个后继。  二叉树的存储结构有两种: 顺序存储结构和链式存储结构。 1. 顺序存储结构 存储方式: 用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素,即将完全二叉树上编号为i的结点元素存储在一维数组中下标为i-1的分量中。 表示方式:

  27. H A B C D G E F J I K L • #define MAX_TREE_SIZE 100 // 二叉树的最大结点数typedef TElemType SqBiTree[MAX_TREE_SIZE]; // 0号单元存储根结点SqBiTree bt; 完全二叉树 图6.4 二叉树与顺序存储结构

  28. 对于一般二叉树,则应将其每个结点与完全二叉树上的结点相对照,存储在一维数组的相应分量中。对于一般二叉树,则应将其每个结点与完全二叉树上的结点相对照,存储在一维数组的相应分量中。 图6.5 单支二叉树与其顺序存储结构

  29. 显然,这种顺序存储结构仅适用于完全二叉树。因为,在最坏的情况下,一个深度为 k 且只有 k 个结点的单支树(树中不存在度为 2 的结点)却需要长度为2k-1的一维数组。

  30. 2. 链式存储结构 1)二叉链表的定义 对于任意的二叉树来说,每个结点只有两个孩子,一个双亲结点。我们可以设计每个结点至少包括三个域:数据域、 左孩子指针域和右孩子指针域: 其中,lchild域指向该结点的左孩子,data域记录该结点的信息,rchild域指向该结点的右孩子。

  31. 用C语言可以这样声明二叉树的二叉链表结点的结构: • typedef struct BiTNode • { • TElemType data;  //结点数据 • struct BiTNode *lchild; //左孩子指针 • struct BiTNode *rchild; //右孩子指针 • }BiTNode, *BiTree;

  32. 图6.6 二叉树和二叉链表

  33. 二叉链表中有几个空链域? 若一个二叉树含有n个结点,则它的二叉链表中必含有2n个指针域, 其中必有n+1个空的链域。此结论证明如下: 证明:分支数目B=n-1,即非空的链域有n-1个,故空链域有2n-(n-1)=n+1个。 

  34. 表示方式:typedef struct TriTNode {TElemType data;struct TriTNode *lchild, *rchild; // 左右孩子指针struct TriTNode *parent; // 双亲指针} TriTNode, *TriTree; 2)三叉链表 有时,为了便于找到父结点,可以增加一个parent域, parent域指向该结点的双亲结点。 该结点结构如下:

  35. 采用哪种存储结构 • 考虑: 1)二叉树的形态 2)进行何种操作

  36. 练习题: 1、按照二叉树的定义,具有3个结点的二叉树有种。 A. 3 B. 4 C. 5 D. 6 答案: C 2、深度为5的二叉树至多有个结点。 A. 16 B.32 C.31 D.10 答案: C 3、对一个满二叉树,m个树叶,n个结点,深度为h,则。 A.n=h+m B.h+m=2n C.m=h-1 D.n=2h-1 答案: D

  37. 4、高度为h的完全二叉树至少有多少个结点?至多有多少个结点?4、高度为h的完全二叉树至少有多少个结点?至多有多少个结点? 解: 至少有:2h-1,至多有:2h-1

  38. A B C E D G F H I J K L M N 5、假设在树中,结点x是结点y的双亲时,用(x,y)来表示树边。已知一棵树边的集合为:{(I,M),(I,N),(B,E),(E,I),(B,D),(A,B),(G,J),(G,K),(C,G),(C,F),(H,L),(C,H),(A,C)},用树形表示法画出此树。 解:该树为:

  39. 6、一棵度为2的树与一棵二叉树有何区别? 解: 区别(1)度为2的树至少有一个结点有二个分支,二叉树的每个结点的分支数都可以小于2; (2)度为2的树两个分支没有左右之分;二叉树的两个分支,有左右之分,且左右不能交换。

  40. 具有3个结点的树 3个结点的二叉树 7、试分别画出具有3个结点的树和3个结点的二叉树的所有不同形态。 解:

  41. A A B C B C D E F G D E F A A B C B C D E D 8、深度为3的完全二叉树有哪几种形式?

  42. 6.3 二叉树的遍历与线索化 6.3.1遍历二叉树 二叉树的遍历是指按照某种顺序访问二叉树中的每个结点,使每个结点被访问一次且仅被访问一次。 • 遍历是二叉树中经常要用到的一种操作。因为在实际应用问题中,常常需要按一定顺序对二叉树中的每个结点逐个进行访问,查找具有某一特点的结点,然后对这些满足条件的结点进行处理。 • 通过一次完整的遍历,可使二叉树中结点信息由非线性排列变为某种意义上的线性序列。也就是说,遍历操作使非线性结构线性化。

  43. 我们用L、D、R分别表示遍历左子树、访问根结点、 遍历右子树, 那么对二叉树的遍历顺序就可以有六种方式:  • (1) 访问根,遍历左子树,遍历右子树(记做DLR)。  • (2) 访问根,遍历右子树,遍历左子树(记做DRL)。  • (3) 遍历左子树,访问根,遍历右子树(记做LDR)。  • (4) 遍历左子树,遍历右子树,访问根(记做LRD)。  • (5) 遍历右子树,访问根,遍历左子树(记做RDL)。  • (6) 遍历右子树,遍历左子树,访问根(记做RLD)。

  44. 注意:先序、中序、后序遍历是递归定义的, 即在其子树中亦按上述规律进行遍历。 下面就分别介绍三种遍历方法的递归定义。  1. 先序遍历(DLR)操作过程:  若二叉树为空, 则空操作, 否则依次执行如下3个操作:  (1) 访问根结点;  (2) 按先序遍历左子树;  (3) 按先序遍历右子树。

  45. 2 .中序遍历(LDR)操作过程:  若二叉树为空, 则空操作, 否则依次执行如下3个操作: (1) 按中序遍历左子树;  (2) 访问根结点;  (3) 按中序遍历右子树。  3. 后序遍历(LRD)操作过程:  若二叉树为空, 则空操作, 否则依次执行如下3个操作: (1) 按后序遍历左子树;  (2) 按后序遍历右子树;  (3) 访问根结点。

  46. 对于如图所示的二叉树, • 先序遍历: A、 B、 D、 F、 G、 C、 E、 H 。 • 中序遍历: B、 F、 D、 G、 A、 C、 E、 H 。  • 后序遍历: F、 G、 D、 B、 H、 E、 C、 A 。

  47. 最早提出遍历问题是对存储在计算机中的表达式求值。例如:(a+b*c)-d/e。该表达式用二叉树表示如下图所示。当我们对此二叉树进行先序、中序、后序遍历时,便可获得表达式的前缀、 中缀、 后缀书写形式:  • 前缀: -+a*bc/de  • 中缀: a+b*c-d/e  • 后缀: abc*+de/-  • 其中中缀形式是算术表达式的通常形式,只是没有括号。 前缀表达式称为波兰表达式。算术表达式的后缀表达式被称作逆波兰表达式。 在计算机内, 使用后缀表达式易于求值。

More Related