数据结构树与二叉树详细解析ppt课件.ppt
《数据结构树与二叉树详细解析ppt课件.ppt》由会员分享,可在线阅读,更多相关《数据结构树与二叉树详细解析ppt课件.ppt(162页珍藏版)》请在三一办公上搜索。
1、树的概念 二叉树 二叉树遍历 线索化二叉树 树与森林 Huffman树,第4章 树与二叉树,1,2,树形结构是一种非线性结构,应用十分广泛。如:行政机构、磁盘目录、家谱等,3,磁 盘 目 录,树和森林的概念,树的定义 树是由 n (n 0) 个结点组成的有限集合。如果 n = 0,称为空树;如果 n 0,则有一个特定的称之为根(root)的结点,它只有直接后继,但没有直接前驱;除根以外的其他结点划分为 m (m 0) 个 互不相交的有限集合T0, T1, , Tm-1,每个集合又是一棵树,并且称之为根的子树。,4,树的特点,每棵子树的根结点有且仅有一个直接前驱,但可以有0个或多个直接后继。,A
2、,C,G,B,D,E,F,K,L,H,M,I,J,5,6,例5.1: Tree=(D, R)D=Book, C1, C2, C3, S1.1, S1.2, S2.1, S2.2, S2.3, S2.1.1, S2.1.2 R=, , , , , , , , , ,树是一种层次结构 (hierarchy structure),7,基本术语:主要来源于家谱和树双亲、子女(parent, child):若 R,则称a是b的双亲,b是a 的子女(孩子);结点度(degree):结点所拥有的子女数;叶(leaf):度为0的结点;分枝结点(branch node):度大于0的结点;树的度:树中最大的结点度
3、;,8,结点所在的层次(level):根在第1层,其它任一结点所在的层是其双亲的层加1;深度或高(depth):结点所在的层次的最大层数;兄弟(sibling):具有同一双亲的结点互称兄弟;堂兄弟(cousin):双亲在同层的非兄弟结点互称堂兄弟;,9,祖先、子孙(ancestor):一个结点是它所有子树中的结点的祖先,这些结点是它的子孙;路径(path):是一结点序列n1,n2,n3,nk,并且前1个结点是后1个结点的双亲;它的长度是k-1;有序树(ordered tree):每个结点的子女由左到右是有次序的;否则是无序树;,10,结点A、B、C的度分别为:3、2、1,叶子:K,L,F,G,
4、M,I,J,结点A的孩子:B,C,D结点B的孩子:E,F,结点I的双亲:D结点L的双亲:E,结点B,C,D为兄弟结点K,L为兄弟,树的度:3,结点A的层次:0结点M的层次:3,树的深度:3,结点F,G为堂兄弟结点A是结点F,G的祖先,11,森林(Forest): m(m 0)棵互不相交的树的集合.,二叉树 (Binary Tree),二叉树的五种不同形态,L,12,性质1 若二叉树的层次从1开始, 则在二叉树的第 i 层最多有 2i -1个结点。(i 1) 证明用数学归纳法性质2 深度为 k 的二叉树最多有 2k-1个结点。(h 1) 证明用求等比级数前k项和的公式 20 + 21 + + 2
5、k-1 = 2k-1,二叉树的性质,13,性质3 对任何一棵二叉树, 如果其叶结点有 n0 个, 度为2的非叶结点有 n2 个, 则有 n0n21证明:若设度为1的结点有 n1 个,总结点个数为 n,总边数为 e,则根据二叉树的定义, n = n0 + n1 + n2 e = 2n2 + n1 = n - 1因此,有 2n2 + n1 = n0 + n1 + n2 - 1 n2 = n0 - 1 n0 = n2 + 1,14,定义1 满二叉树 (Full Binary Tree) 定义2 完全二叉树 (Complete Binary Tree) 若设二叉树的高度为h,则共有h+1层。除第 h
6、层外,其它各层 (0 h-1) 的结点数都达到最大个数,第 h 层从右向左连续缺若干结点,这就是完全二叉树。(特点),15,叶结点仅在层次最大的两层出现对任一结点,若其右子树的高度为l,则其左子树的高度为l或l+1,16,性质4 具有 n (n 0) 个结点的完全二叉树的高度为 log2(n+1) -1 证明:设完全二叉树的高度为 h,则有 2h - 1 n 2h+1 - 1变形 2h n+1 2h+1 取对数 h log2(n+1) h+1 有 log2(n+1) = h+1 h = log2(n+1) -1,上面h层结点数,包括第h层的最大结点数,17,性质5 如将一棵有n个结点的完全二叉
7、树自顶向下,同一层自左向右连续给结点编号0, 1, 2, , n-1,则有以下关系: 若i = 0, 则 i 无双亲 若i 0, 则 i 的双亲为(i -1)/2 若2*i+1 n, 则 i 的左子女为 2*i+1,若 2*i+2 n, 则 i 的右子女为2*i+2 若 i 为偶数, 且i != 0, 则其左兄弟为i-1, 若 i 为奇数, 且i != n-1, 则其右兄弟为i+1结点i所在的层次为 log2(i+1),18,二叉树的抽象数据类型,ADT BinaryTree is Data 是有限个结点的集合D。当D非空时,其中 有一根结点t,其余结点被分为t的左子树和 右子树。 Opera
8、tions Constructor Process: 建立一棵空二叉树 Delete Process: 删除二叉树,19,20,IsEmpty Process: 判断二叉树是否是空 Output: 若二叉树为空,则返回true, 否则返回false Size Process: 计算二叉树的结点数size Output: size Height Process: 计算二叉树的高度height Output: height Root Process: 取二叉树根结点值x Output: 根结点值x,21,Parent Input: node是二叉树中的一个结点 Process: 求node的双亲p
9、,若node 是根,则p为空 Output: p CreateBinaryTree Input: 二叉树的某种形式的定义definition Process: 根据此定义definition构造二叉树 MakeTree Input: data是根结点值,left是左子树,right是右子树 Process: 创建二叉树,data是根结点值,left是其左子树, right是其右子树,22,BreakTree Process: 拆分二叉树,data是根结点数据,left是左子树, right是右子树 Output: data, left, right PreOrder Input: Visit(
10、)是结点访问函数 Process: 按前序遍历对二叉树中每个结点调用Visit( )1次且仅1次 Output: 根据Visit( ),按前序遍历序列得到结果 InOrder Input: Visit()是结点访问函数 Process: 按中序遍历对二叉树中每个结点调用Visit( ) 1次且仅1次 Output: 根据Visit( ),按中序遍历序列得到结果,23,PostOrder Input: Visit()是结点访问函数 Process: 按后序遍历次序对二叉树中每个结点调用Visit( ) 1次且 仅1次 Output: 根据Visit( ),按后序遍历序列得到结果 LevelOrd
11、er Input: Visit()是结点访问函数 Process: 按层次对二叉树中每个结点调用Visit( )1次且仅1次 Output: 根据Visit( ),按层次遍历序列得到结果/ BinaryTree,完全二叉树 一般二叉树的顺序表示 的顺序表示,二叉树的顺序表示,24,极端情形: 只有右单支的二叉树,25,二叉树的链表表示,二叉链表,26,二叉树的链表表示,三叉链表,27,二叉树链表表示的示例,二叉树 二叉链表 三叉链表,28,29,二叉链表中结点定义如下:class BinaryTreeNode DataType data; BinaryTreeNode *leftChild,
12、*rightChild; /左指针,右指针 public : BinaryTreeNode(DataType /BinaryTreeNode,二叉树的链表式实现,30,class BinaryTree BinaryTreeNode *root; /根结点指针 public : BinaryTree( ) root = NULL; /创建一个空的二叉树 bool IsEmpty( ); /如果二叉树为空,则返回true,否则返回false bool Root(DataType /通过扩充二叉树的前序遍历序列,创建二叉树,二叉链表定义如下:,31,void MakeTree(DataType /逐
13、层遍历,/其中,Visit作为遍历的过程参数,负责对结点的访问。,32,void Delete(BinaryTreeNode * ,33,bool Root(DataType /创建新二叉树 ,二叉树遍历,二叉树的遍历是按某种次序访问树中的结点,要求每个结点访问一次且仅访问一次。 设访问根结点记作 V, 遍历根的左子树记作 L, 遍历根的右子树记作 R,,34,可能的遍历次序,前序 VLR 镜像 VRL中序 LVR 镜像 RVL后序 LRV 镜像 RLV,35,前序遍历:若BT非空,则:1.访问根;2.前序遍历左子树;3.前序遍历右子树;,中序遍历:若BT非空,则:1.中序遍历左子树;2.访问
14、根3.中序遍历右子树;,后序遍历:若BT非空,则:1.后序遍历左子树;2.后序遍历右子树;3.访问根,遍历算法,36,遍历结果 中序: a + b * c - d - e / f 前序:- + a * b - c d / e f 后序: a b c d - * + e f / -,37,38,练习:,给出上述二叉树的前序、中序和后序的遍历序列,前序遍历序列:ABDGCEFH中序遍历序列:DGBAECHF后序遍历序列:GDBEHFCA,39,前序遍历的二叉树递归算法void BinaryTree: preOrder (BinaryTreeNode * ,40,二叉树递归的中序遍历算法void B
15、inaryTree: InOrder (BinaryTreeNode * ,41,二叉树递归的后序遍历算法void BinaryTree: postOrder (BinaryTreeNode * ,利用二叉树后序遍历计算二叉树结点个数,int Size (BinaryTreeNode *,应用二叉树遍历的事例,42,int Depth (BinaryTreeNode *,利用二叉树后序遍历计算二叉树的高度,43,以递归方式建立二叉树。递归出口:当遇到时,是空。建立根结点。建立左子树和右子树。二叉树用根字符序列和左右子树的字符序列表示,空树用空格(或某一字符表示)表示。 例如用“”或用“-1”表
16、示字符序列或正整数序列空结点。,利用二叉树前序遍历建立二叉树,44,如图所示的二叉树的前序遍历顺序为A B C D E G F 序列是扩充二叉树的前序遍历序列。是扩充的叶结点,它代表空指针。,45,46,建立二叉树(二叉链表)算法:void CreateBinaryTree(BinaryTreeNode* CreateBinaryTree,遍历二叉树的非递归算法,我们先观察一下三种遍历行走的路线前序遍历,*,*,*,*,*,*,*,*,*,47,#,#,#,#,#,#,#,#,#,中序遍历,48,&,&,&,&,&,&,&,&,&,后序遍历,49,三种遍历的访问位置对比:,三种遍历的路线是完全
17、一样的,每个结点都被经过三次但访问时间是不同的;,前序:第一次经过时访问,中序:第二次经过时访问,后序:第三次经过时访问,50,算法思想 非递归中序遍历Binary Tree建立栈 stack;P指向根;当p不空 或 stack 不空时反复做: 若 p不空 ,p 入 栈; p指向左子女; 否则: 出栈顶元素到p中;访问p;p指向右子女; 4. 结束,51,52,思考:非递归的前序遍历算法?,中序遍历BinaryTree算法思想 :建立栈 Stack;p指向根;当p不空 或 Stack 不空时反复做: 若 p不空,p 入 栈; p指向左子女; 否则: 出栈顶元素到p中;访问p;p指向右子女; 4
18、. 结束,前序遍历BinaryTree的非递归算法思想 :建立栈 Stack;p指向根;当p不空 或 Stack 不空时反复做: 若 p不空,访问p ,p 入 栈; p指向左子女; 否则: 出栈顶元素到p中;p指向右子女; 结束,53,例,&A,root,54,例,55,&A,&B,&C,(3),例,56,57,(5),例,58,(6),例,P=NULL,59,60,61,62,&A,&D,&E,访问:C B,P=NULL,(10),例,63,&A,&D,访问:C B E,p,(11),例,64,&G,65,66,(14),例,67,&A,&D,访问:C B E G,P=NULL,(15),例
19、,68,69,70,&F,71,72,73,74,75,前序遍历的非递归算法:void PreOrder(BinaryTreeNode *p=root) BinaryTreeNode *p; Stack stack; /建立栈 while (p | !stack.IsEmpty() while(p) stack.Push(p); coutp-data; p=p-leftChild; /向左走 else p=stack.Pop(); p=p-rightChild; /向右走 /while/InOrder,算法思想 非递归后序遍历1.建立栈 stack;2.P指向根;3.当p不空或stack 不空
20、时反复做: 若p不空 :(p,L) 入 栈; p向左走一步; 否则: 出栈顶元到p和tag中; 若tag=R : 访问p;p置空;否则 (p,R)入栈;并 p向右走一步;4. 结束,后序遍历时,访问一个结点的时间是:第3次经过时;第2次返回时;从右边返回时;如何区分从左还是右返回的呢?P入栈时带一标记:向左走时带L向左走时带R,76,77,void PostOrder(void Visit(BinaryTreeNode *)/后序遍历BinaryTreeNode *t=root;Stack stack; /建立栈while (t | !stack.IsEmpty() if (t) stack.
21、Push(t, L); /(t,L)入栈 t=t-leftChild; / t向左走 ,后序遍历二叉树非递归算法(基于二叉链表存储结构),78,else e=stack.Pop(); /出栈顶元素到e中 t=e.t; tag=e.tag; if (tag=R) t-data; t=NULL; else stack.Push(t,R);t=t-rightChild; /t向右走 /if /while/postOrder,79,例:,B,E,A,C,root,(A.L) 入栈 (A.L)(B.L) 入栈 (A.L)(B.L)(B.L)退栈 (A.L)(B.R)入栈 (A.L) (B.R)(E.L)
22、入栈 (A.L) (B.R) (E.L)(E.L)退栈 (A.L) (B.R)(E.R)入栈 (A.L) (B.R) (E.R)(E.R)退栈 (A.L) (B.R) 访问E(B.R)退栈 (A.L) 访问B(A.L)退栈 (A.R)入栈 (A.R)(C.L)入栈 (A.R) (C.L)(C.L)退栈 (A.R) (C.R)入栈 (A.R) (C.R)(C.R)退栈 (A.R)访问C(A.R)退栈 访问A,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,80,已知二叉树的前序遍历序列和中
23、序遍历序列 或二叉树中序遍历序列和后序遍历序列,如何确定一棵二叉树?,例:已知一棵二叉树的 前序遍历序列:HDACBGFE 中序遍历序列:ADCBHFEG试画出满足以上序列的二叉树?,81,例:已知一棵二叉树的中序遍历序列:ADCBHFEG后序遍历序列:ABCDEFGH试画出满足以上序列的二叉树?,课堂练习:前序遍历序列:ABDGHJKECFIM中序遍历序列:GDJHKBEACFMI试画出满足以上序列的二叉树,82,考虑层次遍历算法LevelOrder ?,层次遍历序列:ABCDEFGH,83,void BinaryTree:LevelOrder ( ) /层次遍历二叉树算法 SeqQueue
24、 qu; BinTreeNode *p=root; qu.Enter(p); while(!qu.IsEmpty( ) p=qu.Leave( ); coutdata; if(p-leftChild) qu. Enter(p-leftChild); if(p-rightChild) qu. Leave(p-rightChild);,线索的目的:利用二叉树的空指针保存遍历序列的前驱、后继信息,遍历二叉树时不需要栈。 n个结点的二叉树,有2n个指针,只用了n-1个,有n+1个是空的。用空的左指针指向遍历序列的前驱用空的右指针指向遍历序列的后继这两种指针称为线索(Thread)。,线索化二叉树 (T
25、hreaded Binary Tree),线索 (Thread),84,85,例:,n个结点的二叉链表中,有2n个指针,只用了n-1个指针,有n+1个指针是空的。,86,给二叉树加线索的过程是线索化(穿线);按前序遍历序列线索化的二叉树是前序线索二叉树;按中序遍历序列线索化的二叉树是中序线索二叉树;按后序遍历序列线索化的二叉树是后序线索二叉树;中序线索二叉树简称线索二叉树;,增加 Pred 指针和 Succ 指针的二叉树,87,88,B,thrt,前序序列:ABCDE前序线索二叉链表,二叉树,89,B,中序序列:BCAED中序线索二叉链表,二叉树,thrt,90,B,后序序列:CBEDA后序线
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 二叉 详细 解析 ppt 课件

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