ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:22.68KB ,
资源ID:8789601      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8789601.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(树和二叉树.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

树和二叉树.docx

1、树和二叉树第六章 树和二叉树6.1 树的类型定义 数据对象D:D是具有相同特性的数据元素的集合。 数据关系R: 若D为空集,则称为空树; 否则:(1) 在D中存在唯一的称为根的数据元素root, (2) 当n1时,其余结点可分为m(m0)个互不相交的有限集 T1, T2, , Tm, 其中每一棵子集本身又是一棵符合本定义的树,称为根root的子树。 基本操作:查找: Root(T); Value(T, cur_e); Parent(T, cur_e); LeftChild(T, cur_e); RightSibling(T, cur_e); TreeEmpty(T); TreeDepth(T)

2、; TraverseTree(T, Visit();插入: InitTree(&T); CreateTree(&T, definition); Assign(T, cur_e, value); InsertChild(&T, &p, i, c);删除: ClearTree(&T); DestroyTree(&T); DeleteChild(&T, &p, i); DestroyTree(&T);有向树 : ) 有确定的根; ) 树根和子树根之间为有向关系有序树和无序树的区别在于: 子树之间是否存在次序关系? 和线性结构的比较 线性结构 树结构第一个数据元素 根结点 (无前驱) (无前驱)最后一

3、个数据元素 多个叶子结点 (无后继) (无后继)其它数据元素 树中其它结点(一个前驱、一个后继) (一个前驱、多个后继)基本术语结点:数据元素 + 若干指向子树的分支结点的度:分支的个数树的度:树中所有结点的度的最大值叶子结点:度为零的结点分支结点:度大于零的结点从根到结点的路径:孩子结点、双亲结点、兄弟结点、祖先结点、子孙结点结点的层次:假设根结点的层次为1, 第l层的结点的子树根结点的层次为l+1树的深度:树中叶子结点所在的最大层次森林:是m(m0)棵互不相交的树的集合任何一棵非空树是一个二元组Tree = (root,F)其中: root被称为根结点,F被称为子树森林6.2 二叉树的类型

4、定义 二叉树或为空树;或是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。 二叉树的五种基本形态:.flash二叉树的建立演示.swf 二叉树的主要基本操作:查找: Root(T); Value(T, e); Parent(T, e); LeftChild(T, e); RightChild(T, e); LeftSibling(T, e); RightSibling(T, e); BiTreeEmpty(T); BiTreeDepth(T); PreOrderTraverse(T, Visit(); InOrderTraverse(T, Visit(); PostOrde

5、rTraverse(T, Visit(); LevelOrderTraverse(T, Visit();插入: InitBiTree(&T); Assign(T, &e, value); CreateBiTree(&T, definition); InsertChild(T, p, LR, c);删除: ClearBiTree(&T); DestroyBiTree(&T); DeleteChild(T, p, LR); 二叉树的重要特性:性质 1 : 在二叉树的第 i 层上至多有2i-1个结点 (i1)性质 2 : 深度为k的二叉树上至多含2k-1个结点 (k1)性质 3 : 对任何一棵二叉树

6、,若他含有n0个叶子结点、n2个度为2的结点,则必存在关系式: n0 = n2+1 两类特殊的二叉树:满二叉树:指的是深度为k且含有2k-1个结点的二叉树完全二叉树:树中所含的n个结点和满二叉树中编号为1至n的结点一一对应性质 4 : 具有n个结点的完全二叉树的深度为 log2n+1性质 5 : 若对含n个结点的二叉树从上到下且从左至右进行1至n的编号,则对二叉树中任意一个编号为i的结点:(1) 若i=1,则该结点是二叉树的根,无双亲, 否则,编号为i/2的结点为其双亲结点;(2) 若2in,则该结点无左孩子, 否则,编号为2i的结点为其左孩子结点;(3) 若2i+1n,则该结点无右孩子结点,

7、 否则,编号为2i+1的结点为其右孩子结点。6.3 二叉树的存储结构一、 二叉树的顺序存储表示 class BiTree private: Array SqBiTree;显然,这种顺序存储结构仅适用于完全二叉树。因为,在最坏的情况下,一个深度为 k 且只有 k 个结点的单支树(树中不存在度为 2 的结点)却需要长度为2k-1的一维数组。二、二叉树的链式存储表示 1. 二叉链表template class BiTreeNode / 二叉树的结点 protected: BiTreeNode *lchild; / 指向左子树的指针BiTreeNode *rchild; / 指向右子树的指针 publ

8、ic: Elem* data; / constructorTreeNode (const Elem& item, BiTreeNode *lptr = NULL, BiTreeNode *rptr = NULL); /virtual destructor. needed for AVL tree class virtual TreeNode(void); / access methods for the pointer fields BiTreeNode* Left(void) const; BiTreeNode* Right(void) const; void AssignLeft(Tree

9、Node* p); void AssignRight(TreeNode* p); / BinSTree needs access to left and right friend class BinSTree; 2三叉链表 protected: BiTreeNode *lchild; / 指向左子树的指针BiTreeNode *rchild; / 指向右子树的指针BiTreeNode *parent; / 指向双亲的指针 3双亲链表 protected: BiTreeNode *parent; / 指向双亲的指针 char LRTag; / 指示左右的标志 4线索链表6.4 二叉树的遍历一、问

10、题的退出顺着某一条搜索路径巡访二叉树中的结点,使得每个结点均被访问一次,而且仅被访问一次。“访问”的含义可以很广,如:输出结点的信息等。对“二叉树”而言,可以有三条搜索路径:1先上后下的按层次遍历;2先左(子树)后右(子树)的遍历;3先右(子树)后左(子树)的遍历。二、先左后右的遍历算法 先(根)序的遍历算法: 若二叉树为空树,则空操作;否则,(1)访问根结点;(2)先序遍历左子树;(3)先序遍历右子树。 中(根)序的遍历算法: 若二叉树为空树,则空操作;否则,(1)中序遍历左子树;(2)访问根结点;(3)中序遍历右子树。 后(根)序的遍历算法: 若二叉树为空树,则空操作;否则,(1)后序遍历

11、左子树;(2)后序遍历右子树;(3)访问根结点。三、算法的递归描述/ preorder recursive scan of the nodes in a tree. template void Preorder (TreeNode *t, void visit(Elem& item) if (t != NULL) visit(t-data); / 访问结点 Preorder(t-Left(), visit); / 遍历左子树 Preorder(t-Right(), visit); / 遍历右子树 四、中序遍历算法的非递归描述/ return address of last node on th

12、e left branch / from t, stacking nodes on the way. used for / iterative inorder scan.template TreeNode *GoFarLeft(TreeNode *t, StackTreeNode *& S) if (t = NULL) return NULL; while (t-Left( ) != NULL) S.Push(t); t = t-Left(); return t;/ inorder iterative scantemplate void Inorder_I(TreeNode *t, void

13、visit(Elem& c) StackTreeNode* S; t = GoFarLeft(t,S); / continue until t is NULL while(t != NULL) visit(t-data); if (t-Right( ) != NULL) t = GoFarLeft(t-Right( ),S); else if ( !S.StackEmpty( ) t = S.Pop(); else t = NULL; / we are done 五、遍历算法的应用举例:1、统计二叉树中叶子结点的个数/ 先序遍历template void CountLeaf (TreeNode

14、 *t, int& count) if (t != NULL) if (t-Left( ) = NULL & t-Right( ) = NULL) count+; CountLeaf(t-Left( ), count); CountLeaf(t-Right( ), count); 2、求二叉树的深度(后序遍历)template int Depth (TreeNode *t) int depthLeft, depthRight, depthval; if (t = NULL) depthval = 0; else depthLeft = Depth(t-Left( ); depthRight=

15、Depth(t-Right( ); depthval = 1 +(depthLeft depthRight? depthLeft:depthRight); return depthval;3、复制二叉树/ 生成一个二叉树的结点template TreeNode *GetTreeNode(Elem item, TreeNode *lptr = NULL, TreeNode *rptr = NULL) TreeNode *p; p = new TreeNode (item, lptr, rptr); if (p = NULL) exit(1); return p;template TreeNode

16、 *CopyTree(TreeNode *t) TreeNode *newlptr, *newrptr, *newnode; if (t = NULL) return NULL; if (t-Left( ) != NULL) newlptr = CopyTree(t-Left( ); else newlptr = NULL; if (t-Right( ) != NULL) newrptr = CopyTree(t-Right( ); else newrptr = NULL; newnode = GetTreeNode(t-data, newlptr, newrptr); return newn

17、ode;4、建立二叉树的存储结构TreeNode* crtTree(char *str, int& i) / 建立由字符串stri.n定义的二叉树,stri为根 TreeNode* t; char Ch = stri; if (Ch = ) t = NULL; else t = GetTreeNode(Ch); / creat the root node i+; t-AssignLeft(crtTree(str, i); i+; t-AssignRight(crtTree(str, i); return t; 建表达式的树由先缀表示式建树由原表达式建树 a+bc(de/f)gTreeNode*

18、 crtTree(char *str) TreeNode* t; StackTreeNode* SD; Stack SP; SP.Push(); p = str; ch = *p; while(!SP.StackEmpty() if (ch 是字母) 建叶子结点t;SD.Push(t); else switch (ch) case (: SP.Push(ch); break;case ): c=SP.Pop(); while (c!=() 建二叉树t;SD.Push(t); c=SP.Pop(); break; defult: while(!SP.Gettop(c)&(precede(c, c

19、h) c=SP.Pop();建二叉树t;SD.Push(t); if (ch!=) SP.Push(ch); else c=SP.Pop(); break; / defult / switch / else if (ch!=) p+; ch=*p; / while t=SD.Pop(); return t; / crtTree由表达式的先缀和中缀表示式建树 a b c d e f ga b c d e f g6.5 线索二叉树一、 何谓线索二叉树?在存储结构中保存遍历所得“前驱”和“后继”的信息线索链表: 对二叉链表的结点增加两个标志域,并作如下规定:若该结点的左子树不空,则lchild域的指

20、针指向其左子树,且左标志域的值为0; 否则,lchild域的指针指向其“前驱”,且左标志的值为1.若该结点的右子树不空,则rchild域的指针指向其右子树,且右标志域的值为0; 否则,rchild域的指针指向其“后继”,且右标志的值为1. 线索链表的结点类:template class ThrNode protected:PointerTag ltag;PointerTag rtag;ThrNode lchild;TheNode rchild; 线索链表的遍历算法: for ( p = firstNode(T); p; p = Succ(p) ) Visit(p);中序线索化链表的遍历算法:.

21、flash中序线索化二叉树演示.swf.flash寻找中序线索化二叉树指定结点的前趋演示.swf 中序遍历的第一个结点? 在中序线索化链表中结点的后继?.flash寻找中序线索化二叉树指定结点的后继演示.swftemplate void InOrderTraverse_Thr(ThrNode *T, void Visit(Elem& item) / t指向头结点,头结点的左链lchild指 / 向根结点,头结点的右链rchild指向中 / 序遍历的最后一个结点。 / 中序遍历二叉线索链表表示的二叉树T。 p = T-Left(); / p指向根结点 while (p != T) / 空树或遍历

22、结束时,p=T while (p-LTG() = Link) p = p-Left();Visit(p-data); / 访问其左子树为空的结点 while(p-RTG()=Thread&p-Right()!= T) p = p-Right(); Visit(p-data); / 访问后继结点 p = p-Right(); / p进至其右子树根 / InOrderTraverse_Thr 如何建立线索链表?在中序遍历过程中保存当前访问结点的“前驱”和“后继”信息template ThrNode* InOrderThreading(ThrNode* T) / 中序遍历二叉树T,并对其进行中序线

23、/ 索化,Thrt指向线索化之后的头结点。 ThrNode* Thrt; Thrt = GetThrNode( , Link, Thread); / 建头结点 Thrt-AssignRight( Thrt); / 右指针回指 if (T = NULL) Thrt-AssignLeft ( Thrt); / 若二叉树空,则左指针回指 else Thrt-AssignLeft(T); pre = Thrt;InThreading(T); /中序遍历进行中序线索化 pre-AssignRight(Thrt); pre-AssignRTag(Thread); / 最后一个结点线索化 Thrt-Assi

24、gnRight (pre); return Thrt; / InOrderThreading附设指针pre,并始终保持指针pre指向当前访问的、指针p所指结点的前驱template void InThreading(ThrNode* p) if (p) InThreading(p-Left(); / 左子树线索化 if (!p-Left( ) p-AssignLTag(Thread); p-AssignLeft(pre); / 建前驱线索 if (!pre-Right( ) pre-AssignRTag(Thread); pre-AssignRight(p); / 建后继线索 pre = p;

25、 / 保持pre指向p的前驱 InThreading(p-Right(); / 右子树线索化 / InThreading6.6 树和森林的表示方法树的三种存储结构一、双亲表示法: #define MAX_TREE_SIZE 100结点结构: typedef struct PTNode Elem data; int parent; / 双亲位置域 PTNode;树结构: typedef struct PTNode nodesMAX_TREE_SIZE; int r, n; / 根结点的位置和结点个数 PTree;二、孩子链表表示法:孩子结点结构: typedef struct CTNode in

26、t child; struct CTNode *next; *ChildPtr;双亲结点结构 typedef struct Elem data; ChildPtr firstchild; / 孩子链的头指针 CTBox;树结构: typedef struct CTBox nodesMAX_TREE_SIZE; int n, r; / 结点数和根结点的位置 CTree;三、树的二叉链表(孩子-兄弟)存储表示法 template class CSNode protected CSNode *firstchild, CSNode *nextsibling; public Elem data; ; 森

27、林和二叉树的对应关系 设森林 F = ( T1, T2, , Tn ); T1 = (root, t11, t12, , t1m); 二叉树 B =( LBT, Node(root), RBT );.flash树、森林与二叉树的转换演示.swf 则由森林转换成二叉树的转换规则为: 若 F = ,则 B = ;否则, 由 ROOT( T1 ) 对应得到 Node(root); 由 (t11, t12, , t1m ) 对应得到 LBT; 由 (T2, T3, Tn ) 对应得到 RBT. 由二叉树转换为森林的转换规则为: 若 B = , 则 F = ;否则,由 Node(root) 对应得到 ROOT( T1 );由LBT 对应得到 ( t11, t12, ,t1m);由RBT 对应得到 (T2, T3, , Tn)由此,树的

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1