武汉软件工程职业学院《数据结构讲义》第13讲 2叉树.docVIP

武汉软件工程职业学院《数据结构讲义》第13讲 2叉树.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
1.熟练掌握各种遍历策略的递归和非递归算法。 . 熟练掌握二叉树的线索化过程以及在中序线索化树上找给定结点的前驱和后继的方法。掌握二叉树的遍历,包括中遍历、前遍历和后遍历方法理解什么是线索,中序线索化二叉树的结构特性及寻找某结点的前驱和后继的方法。 遍历二叉树是指以某种顺序访问二叉树中的每个结点,并且每个结点仅被访问一次。这里“访问”的含义很广,可以是查询结点数据域的内容、输出结点的数据、修改结点的数据或是执行对结点的其他操作。假设遍历时访问结点仅是输出结点数据域的值,那么遍历的结果将是得到一个线性序列。由于二叉树有左、右子树,所以遍历的次序不同,得到的结果就会不同。假设L、T、R分别代表遍历左子树、访问根结点和遍历右子树,则对一棵二叉树的遍历可以有六种不同次序:TLR、LTR、LRT、TRL、RTL、RTL。若约定先左(L)后右(R),再把访问根结点(T)穿插其中,则只有三种不同的遍历次序: TLR、LTR和LRT。它们分别称作先根遍历、中根遍历和后根遍历。 在介绍常用的三种遍历算法之前,先介绍一下遍历的具体方法。例如有一棵二叉树,它有四个结点。为了便于理解遍历的思想,暂时为每个没有子树的结点均补充上相应的空子树,用?表示,见图4-3-1。 设想有一条搜索路线(用虚线表示),它从根结点的左支开始,自上而下自左至右搜索,最后由根结点右支向上出去。不难看出,若考虑到空子树的话,恰好搜索线途径每个有效结点都是三次。把第一次经过就访问的结点列出,它们是A、B、D、C,这就是先根遍历的结果。那么第二此经过才访问的则是中根遍历,其结果是B、D、A、C。第三次经过才访问的是后根遍历,结果是D、B、C、A。 下面介绍三种遍历算法,在算法中将采用二叉链表作为二叉树的存储结构。 4.3.1 先根遍历 先根遍历的递归定义为: 若二叉树非空,则 (1)访问根结点; (2)按先根次序遍历左子树; (3)按先根次序遍历右子树。 否则,遍历结束。 算法4.2为先根遍历二叉树的递归算法,其中访问根结点的操作简化为输出根结点的值,输出格式具体使用时加上,在后面的各种有关算法同样处理。 算法4.2 void Preorder(BTNode *bt) { if (bt) { printf(bt-data); Preorder(bt-lchild); Preorder(bt-rchild); } } 为了进一步理解递归算法,现在结合图4-3-1中的二叉树,对算法4.2的执行情况进行分析,如图4-3-2所示。 在上面的分析中应注意到,算法在对某根结点访问之后,便对其左子树进行先根遍历,即进入下一层递归调用。当返回本层调用时,仍以本层根结点为基础对其右子树进行先根遍历。当从下层递归调用再次返回本层时,接着就从本层调用返回到前一层调用。依次类推,最终返回主程序。此外图4-3-2中,树的深度为3,但递归调用的深度要四层。这是因为在遇到空的子树时,它仍要调用一次Preorder函数,只不过是因为子树的根为空立即返回而已。 如果我们把上面的递归算法写成一个等价的非递归算法,则需要直接使用一个栈,用来暂存某些需要保留的信息。 对于先根遍历二叉树而言,在访问根结点之后,我们可以直接找到这个根的左子树进行遍历;但是当左子树遍历完毕之后,我们还必须沿着已经走过的路线返回到根结点,再通过根结点才能找到它的右子树。因此,在我们从根结点走向它的左孩子之前,必须把根结点的地址(指针)送入一个栈中暂存起来。在左子树遍历完毕之后,我们再按后进先出的原则取回栈顶元素,便得到了根结点的地址,最后遍历根的右子树。 根据上面的思想,容易写出下面的先根遍历二叉树的非递归算法。 算法4.3 void Preorder2(BTNode * bt) { p=bt ; top=0 ; while ( p || top) { if (p) { printf ( p -data); ++p ; s [ top ]=p; p=p- lchild; } else{ p=s[top]; - -top; p=p- rchild; } } } 对照图4-3-1中的二叉树,在先根非递归遍历过程中其栈S的内容变化如图4-3-3所示。 分析上面的算法。假定二叉树有n个结点,由于每个结点仅被访问一次,每个结点的指针要进一次栈,出一次栈,因此,算法中的输出语句、进栈和退栈的操作均被执行n次,算法的时间复杂度为O(n)。 算法中的栈所需要的最大容量与二叉树的深度直接有关。我们可以看出,栈中的元素(结点的指针)序列实际上是由二叉树的根结点到某个结点所经分枝上的结点(指针)所组成的,所以栈中元素的个数最多等于二叉树的深度。我们知道,有n个结点的二叉树的深度的最大值为n,因此栈所需要的最大容量M不超过n。 4.

文档评论(0)

白领文档(原创) + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档