数据结构——二叉树_第1页
数据结构——二叉树_第2页
数据结构——二叉树_第3页
数据结构——二叉树_第4页
数据结构——二叉树_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

1、 (c+) 数据结构二叉树 数据结构二叉树(c+) 【摘要】现实社会中的树书籍的目录、任务大纲、家族族谱之类等等。人们要研究就必须能过将树正确的储存,如何存储又关系到实际的操作。树是否为空,在本学期学习的数据结构的教【1】因为树表现形式的是一种现材中允许树为空。从直观上看树是分实的结构,而0不是自然数。其中树和二叉树是最常支关系定义的层次结构,】【1 见的。数据结构;树;二叉树;遍历;探【关键词】 讨空间; 、二叉树11.1 二叉树T是有限的结点的集合(允许为空),或者由一个根结点u以及分别称为左子树和右子树的两棵互不相交的二叉树u(1)和u(2)组成。若用n,n1和n2分别表示T,u(1)和

2、u(2)的结点数,则有n=1+n1+n2 。u(1)和u(2)有时分别称为T的第一和第二子树。 在二叉树中,每个结点至多有两个孩子,并 且有左、右之分。因此任一结点的孩子不外4种情况:没有孩子;只有一个左孩子;只有一个右孩子;有一个左孩子并且有一个右孩子。(如图 1.1) 图1.1 五种基本形态 (其中 表示空) 1.2 二叉树与度数不超过2的树不同,与度数不超过2的有序树也不同。在有序树中,虽然一个结点的孩子之间是有左右次序的,但若该结点只有一个孩子时,就无须区分其左右次序。而 在二叉树中,即使是一个孩子也有左右之分。 图1.2a (不同的两颗二叉树) 图1.2b(普通的一棵树) 由图可见:

3、(a)和(b)是两棵不同的二叉树。虽然它们与普通的一棵树(作为无序树或有序树)很相似,但它们却不能等同于这棵普通的树。若将这3棵树均看作是有序树,则它们就是相同的了。所以二叉树和树尽管有很多相似 ,但是二叉树不是树的特殊情形。 所以,二叉树是一种人们假设的一种现象,所以允许为空是无争议的。二叉树是一种有序的树,左边是孩子、右边是兄弟。其实可以看作不正式因为人们要赋予做这个规定,同的两棵树。 给孩子兄弟不同的意义。通过这学期的学习发现了一个现象,就是树并没有插入删除操作。对于非线性的树结构,插入删除操作不在一定的法则 规定下,是毫无意义的。因此,只有在具体的应用中,才会有插入删除操作。 2、特殊

4、形态的二叉树 【1】:一棵高度为h2.1满二叉树0且有2h+1-1个结点的二叉树称为满二叉树。 (如图3.1) 图3.1 (满二叉树) 【1】:完全二叉树2.2若一棵二叉树至多只有最下面的两层结点的度数小于2,并且最下面一层结点都集中在该层的最左边,则称这种二叉树为完 )3.2(如图 全二叉树。 图3.2 (完全二叉树) 3、二叉树的遍历以及实现(c+) 3.1二叉树基本上有先序遍历、中序遍历、后序遍历,最开始并不明白为什么有这么多,到了后面才明白,这是不同的应用需要的。例如,删除二叉树,必须先删除左右子树,然后才能删除根节点,这时就要用后序遍历,而判断两个二叉树是否相等,只要子树根节点不同,

5、那么就不等,显然这时要用先序遍历; 3.1.1前序遍历 public: void PreOrder(void (*visit)(T &data) = print) PreOrder(root, visit); private: void p, PreOrder(BTNode* void (*visit)(T &data) if (p) visit(p-data); PreOrder(p-left, visit); PreOrder(p-right, visit); 3.1.2中序遍历 public: void InOrder(void (*visit)(T &data) = print) In

6、Order(root, visit); private: void InOrder(BTNode* p, void (*visit)(T &data) if (p) InOrder(p-left, visit); visit(p-data); InOrder(p-right, visit); 3.1.3后序遍历 public: void PostOrder(void (*visit)(T &data) = print) PostOrder(root, visit); private: void PostOrder(BTNode* p, void (*visit)(T &data) if (p)

7、 PostOrder(p-left, visit); PostOrder(p-right, visit); visit(p-data); 4、二叉树的顺序存储结构 4.1在一棵具有n个结点的近似满二叉树中,我们从树根起,自上到下,逐层从左到右给所有结点编号,就能得到一个足以反映整个二叉树结构的线性序列。所以,顺序存储结构是二叉树的一种特点,按照一定的顺序存储在特定的连续单元中。 (如图4.1) 图4.1 (完全二叉树的结点编号) 我们将数组下标作为结点编号,就可将二叉树中所有结点的标号存储在一维数组中。 (如图4.2) 图4.2 可以看到二叉树的这种表示方式下,各结点之间的逻辑关系是隐含表示的

8、。完全二叉树中,除最下面一层外,各层都充满了结点。每一层的结点个数恰好是上一除最底层外, 层结点个数的2倍。因此,从一个结点的编号就可推知其父亲,左孩子、右兄弟,等各结点的编号。 假设对结点为i 的二叉树有如下定义: 1. 仅当i=1时,结点i为根结点; 2. 当i1时,结点i的父结点为i/2; 3. 结点i的左孩子结点为2i; 4. 结点i的右孩子结点为2i+1; 5. 当i为奇数且不为1时,结点i的左兄弟结点为i-1; 6. 当i为偶数时,结点i的右兄弟结点为i+1。 4.2但对于一般的二叉树,采用顺序存储时,为了能用结点在数组中的位置来表示结点之间的逻辑关系,也必须按近似满二叉树的形式来

9、存储树中的结点。一个只有k个结k个结点的存储空2-1点的右单枝树却需要 间。的右单二叉树,添上虚结点3假设结点为)4.2图如(。树叉二满似近棵一为成,后 可知这样造4.3 图 成的存储空间的浪费 、索化二叉树5当用二叉链表作为二叉树的存储结构时,5.1因为每个结点中只有指向其左、右孩子结点的指针,所以从任一结点出发只能直接找到该结点的左、右孩子。在一般情况下靠它无法直接找到该结点在某种遍历序下的前驱和后继结点。如果在每个结点中增加指向其前驱和后继结点的指针,将降低存储空间的效率。 例:一棵中序线索二叉树如(图5.1): 5.1 图 5.2 图 (线索链表)由图5.2可知:在二叉树的线索链表上增

10、加了一个头结点,其LeftChild指针指向二叉树的根结点,其RightChild指针指向中序遍历时的最后一个结点。另外,二叉树中依中序列表的第一个结点的LeftChild指针,和最后一个结点的RightChild指针都指向头结点。这就像为二叉树建立了一个双向线索链表,既可从第一个结点起,顺着后继进行遍历,也可从最后一个结点起顺着前驱进行遍历。 6、探讨线索化二叉树是否降低空间效率 线索化二叉树提出的缘由:7.1 第一,二叉树的叶子节点还有两个指针域没有用,可以节省内存。 第二,我们想用比较少的时间,寻找二叉树 某一个遍历线性序列的前驱或者后继。当然,这样的操作很频繁的时候,做这方面的改善才是

11、有意义的。 7.2证明:求遍历后的线性序列的前驱和后继。 7.2.1先序线索化能依次找到后继,但是前驱需要求双亲;中序线索化前驱和后继都不需要求双亲,但是都不很直接;后序线索化能依次找到前驱,但是后继需要求双亲。可以看出,线索化成中序是最佳的选择,基本上算是达到了要求。 7.2.2节省内存:线索化增加了两个标志位,但是这两个位怎么储存?即使是在支持位存储的CPU上,也不能拿位存储器来存的,第一是因为结构体成员变量的内存地址是在连续的一起的,第二是位存储器的存储数目是有限的。目前的计算机最少需要1个字节来储存这两个标志位。而为了传输速度和内存移植,大部分的内存是要对齐的,这就导致 在内存中使用线索化二叉树根本就没节省内存。假设把个内存空间用来储存双亲指针时,带来的方便绝对不是线索化所

温馨提示

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

评论

0/150

提交评论