学习Excel技术,关注微信公众号:

excelperfect

在上一篇文章《基础扩展| 21. 遍历二叉树》中,我们给出了遍历二叉树的三种方式:前序遍历、中序遍历、后序遍历,以及对应的规则和示意图。下面,我们给出实现这三种遍历算法的VBA代码并详细解析代码的运行过程。

本文使用的二叉树来自于:

基础扩展 | 20. 建立二叉树

中创建的二叉树,代码如下:

Const MAXSIZE = 100

Type BinaryTreeNode

Value As String

LeftChild As Integer

RightChild As Integer

End Type

Type BinaryTree

Node(MAXSIZE) As BinaryTreeNode

Root As Integer

End Type

Public btTree As BinaryTree

Sub CreatBinaryTree()

Dim arr As Variant

Dim i As Long

arr = Array("","A", "B", "C", "D", "E","F", "G", "H", "I", "J","")

btTree.Root = 1

For i = 1 To UBound(arr)

btTree.Node(i).Value= arr(i)

Next i

For i = 1 To UBound(arr)

IfbtTree.Node(i).Value <> "" Then

If btTree.Node(2* i).Value <> "" Then

btTree.Node(i).LeftChild = 2 * i

End If

If btTree.Node(2* i + 1).Value <> "" Then

btTree.Node(i).RightChild = 2 * i + 1

End If

End If

Next i

End Sub

创建的二叉树如下图1所示。

图1

本文实现遍历的算法都采用了递归方式,非常简洁明了。对照代码的运行,仔细体会,不仅有助于理解这些算法,而且有助于加深对递归原理的理解。

前序遍历算法

前序遍历算法的代码如下:

Sub PreOrder(i As Integer)

If btTree.Node(i).Value<> "" Then

Debug.Print btTree.Node(i).Value

PreOrder btTree.Node(i).LeftChild

PreOrder btTree.Node(i).RightChild

End If

End Sub

使用下面的测试代码来调用PreOrder过程:

Sub testPreOrder()

Call PreOrder(btTree.Root)

End Sub

下面来详细看看程序是怎么运行的。

1.代码将btTree.Root(根结点)的值(编号1)传递给PreOrder过程,由于根结点不为空,因此执行Debug.Print btTree.Node(i).Value语句,打印结点数据A,如下图2所示。

图2

2.接着执行语句PreOrder btTree.Node(i).LeftChild,访问结点A的左子树,因为其结点值不为空,执行Debug.Print btTree.Node(i).Value语句,打印结点数据B,如下图3所示。

图3

3.再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点B的左子树,因为其结点值不为空,执行Debug.Print btTree.Node(i).Value语句,打印结点数据D,如下图4所示。

图4

4.再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点D的左子树,因为其结点值不为空,执行Debug.Print btTree.Node(i).Value语句,打印结点数据H,如下图5所示。

图5

5.再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点H的左子树,此时其结点值为空,过程返回;接着调用PreOrder btTree.Node(i).RightChild语句,访问结点H的右子树,其值也为空,过程返回。该层递归调用过程执行完毕,返回到上一级递归调用过程,即调用结点D的过程。此时,递归调用执行PreOrder btTree.Node(i).RightChild语句,访问结点D的右子树,打印结点数据I,如下图6所示。

图6

6.再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点I的左子树,此时其结点值为空,过程返回;接着调用PreOrder btTree.Node(i).RightChild语句,访问结点I的右子树,其值也为空,过程返回。该层递归调用过程执行完毕,返回到上一级递归调用过程,即打印结点D时的过程,该过程也执行完毕。也返回到上一级递归过程,即打印节点B的过程,递归调用执行PreOrder btTree.Node(i).RightChild语句,访问结点B的右子树,打印结点数据E,如下图7所示。

图7

7. 再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点E的左子树,因为其结点值不为空,执行Debug.Print btTree.Node(i).Value语句,打印结点数据J,如下图8所示。

图8

8. 再次执行语句PreOrder btTree.Node(i).LeftChild,访问结点J的左子树,此时其结点值为空,过程返回;接着调用PreOrder btTree.Node(i).RightChild语句,访问结点J的右子树,其值也为空,过程返回。该层递归调用过程执行完毕,返回到上一级递归调用过程,即打印结点E时的过程,递归调用执行PreOrder btTree.Node(i).RightChild语句,访问结点E的右子树,其结点值为空,过程返回。此时该层递归过程执行完毕,返回到上一级递归调用过程,即打印结点B时的过程,也执行完毕。再向上一层返回到打印节点A时的过程,调用PreOrder btTree.Node(i).RightChild语句,访问结点A的右子树,因为其结点值不为空,执行Debug.Print btTree.Node(i).Value语句,打印结点数据C,如下图9所示。

图9

9.类似前面的递归调用,依次继续打印结点F、G。

综上,前序遍历这棵二叉树的结点顺序是:ABDHIEJCFG。

本文所讲解的前序遍历原理也可以参考《大话数据结构》的P178-P181。

c 打印二叉树_基础扩展 | 22. 遍历二叉树—前序遍历算法的VBA代码解析相关推荐

  1. excel 进行二叉树_基础扩展 | 20. 建立二叉树

    学习Excel技术,关注微信公众号: excelperfect 先看看下图1所示的一棵完全二叉树,图中标出了结点的内容.结点编号以及上下层子树之间的关系. 图1 可以看出,如果我们将根结点编号为1,下 ...

  2. excel 进行二叉树_基础扩展 | 21. 遍历二叉树

    学习Excel技术,关注微信公众号: excelperfect 二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中的所有结点,使得每个结点被访问一次且仅被访问一次.下面,以图1所示的二叉树为例 ...

  3. 二叉树为空意味着二叉树_我是怎么调试出来二叉树的遍历(超精彩配图),从此遍历不再愁了...

    推荐学习 牛掰!"基础-中级-高级"Java程序员面试集结,看完献出我的膝盖 数据结构与算法,程序员必过的坎?不掌握一定挤不进BATJ的神技? 我是怎么调试出来二叉树的遍历(超精彩 ...

  4. python实现二叉树遍历(前序遍历、中序遍历、后序遍历)

    python实现二叉树遍历(前序遍历.中序遍历.后序遍历) 在计算机科学中,二叉树是一种树数据结构,其中每个节点最多有两个子节点,称为左子节点和右子节点.使用集合理论概念的递归定义是(非空)二叉树是元 ...

  5. 玩转二叉树 (25 分) 知中序遍历和前序遍历,求做个镜面反转后的层序遍历

    题目: 给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列.所谓镜面反转,是指将所有非叶结点的左右孩子对换.这里假设键值都是互不相等的正整数. 输入格式: 输入第 ...

  6. 【二叉树】根据后续和中序遍历输出前序遍历 [建树+非建树做法]

    F . 案例 4-1.1:根据后续和中序遍历输出前序遍历 Description 本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果. Input 第一行给出正整数N (≤3 ...

  7. 二叉树的四种遍历方法(前序遍历、中序遍历、后序遍历、层序遍历)有图有真相!!!

    文章目录 二叉树的四种遍历方式 前序遍历(Preorder Traversal) 中序遍历(Inorder Traversal) 后序遍历(Postorder Traversal) 层序遍历(Leve ...

  8. 二叉树的三种遍历方式-前序遍历,中序遍历,后序遍历

    二叉树的遍历 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问.访问结点所做的操作依赖于具体的应用问题(比如:打印节点内容.节点内容加1). 遍历是二叉树上 ...

  9. 二叉树的层序遍历,前序遍历(递归,非递归),中序遍历(递归,非递归),后续遍历(递归,非递归)

    文章目录 二叉树的层序遍历 前序遍历 递归版本 非递归版本 中序遍历 递归版本 非递归版本 后序遍历 递归版本 非递归版本 二叉树的层序遍历 void printTree(BinaryTree* ar ...

  10. LeetCode 144. 二叉树的前序遍历(前序遍历)

    文章目录 1. 题目信息 2. 解题 2.1 递归 2.2 循环,必须掌握 1. 题目信息 给定一个二叉树,返回它的 前序 遍历. 示例:输入: [1,null,2,3] 1\2/3 输出: [1,2 ...

最新文章

  1. Ubuntu 常用操作
  2. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链(上)
  3. web项目html页面过多,详解webpack4多入口、多页面项目构建案例
  4. 利用索引数组排序 不改变原数组值的位置
  5. Shell编程之多命令顺序执行和管道符
  6. SharePoint Windows Workflow Foundation
  7. 【数据库实验】《小型MIS的开发》PyQt5 开发 民航票务管理系统
  8. 快速通过软件设计师考试方法
  9. 蓝桥杯 ADV-84 算法提高 图形输出
  10. Typescript 类型的常用知识与技能
  11. Javascript第六章基本数据类型和引用数据类型第三课
  12. python Web开发你要理解的WSGI uwsgi详解
  13. EtherCAT工业以太网的主要特点
  14. 虚拟现实的伦理问题----陈教授讲座听后感
  15. 测试人员的绩效考核,看看你有哪些没做好
  16. Frequency-tuned Salient Region Detection (频率调谐显著性区域检测)
  17. 面向建筑应用的三维点云数据获取和处理的计算方法
  18. java转义字符之换行字符
  19. Mac安装多版本java
  20. 个人收款码和个人经营收款码的区别,你知道吗

热门文章

  1. 基本入门的C/C++算法总结
  2. 李开复谈软件外包及软件安全(一)
  3. spring 事务源码(三)如何保证被@Transactional标记方法中的所有sql都在一个事务内
  4. Git合并分支代码到主分支的方法总结
  5. centOS7安装node+mongoDB+redis+express(forerver)+nginx+https
  6. Hibernate中创建Session(会话)接口的方法
  7. nodejs 做后台的一个完整业务整理
  8. MySQL保存历史执行语句
  9. HDU 1242 特殊化带结构体BFS
  10. 装饰模式(Decorate Pattern)