Go语言实现二叉树遍历

Python012

Go语言实现二叉树遍历,第1张

图例如下:

结果应该是分别是:

广度优先: a ->b ->c ->d ->f ->e ->g

先序遍历: a ->b ->d ->e ->f ->g ->c

中序遍历: e ->d ->b ->g ->f ->a ->c

后序遍历: e ->d ->g ->f ->b ->c ->a

结果存在result里面,如果不存可以少一层变量

这个地方强烈建议读一下下面的第一个链接,我遵照着那篇文章实现的,只是用Go改写了而已。

首先定义一个数据结构,用来存储一些Node的信息。

这里是可以运行的,但是总会抛出一个数组越界的错误,我看了半天也没看出来哪里有问题,Mac版的devel我这边又有bug,没用起来。至少思路对了,我后面再看一下哪里的问题。(感谢 @RiXu 指正)

请实现两个函数,分别用来序列化和反序列化二叉树

二叉树的序列化就是采用前序遍历二叉树输出节点,再碰到左子节点或者右子节点为None的时候输出一个特殊字符”#”。对于反序列化,就是针对输入的一个序列构建一棵二叉树,我们可以设置一个指针先指向序列的最开始,然后把指针指向位置的数字转化为二叉树的结点,后移一个数字,继续转化为左子树和右子树。

序列化:比较简单,直接用递归的办法前序遍历二叉树,其中碰到空就加个#。

反序列化:这里也是在别人的GitHub上借鉴的灵感。这里引入了一个全局的变量flag,通过flag来控制序列化后的索引。这样在递归的时候可以一直把序列化结果S不加改变的放入递归函数中。递归结束的出口是当判断到#的时候,这说明到达了底部,需要返回上一级。依次递归的构建二叉树。

先序遍历先从二叉树的根开始,然后到左子树,再到右子树。

遍历的结果是:ABDCEF

中序遍历先从左子树开始,然后到根,再到右子树。

遍历的结果是:DBAECF

后序遍历先从左子树开始,然后到右子树,再到根。

遍历的结果是:DBEFCA

打印自己,然后先遍历左节点再遍历右节点

这里的栈用处是为了保存二叉树的结构,以弥补二叉树无法获取父节点的结构特性。

不过需要注意的是后入栈的为左孩子,以保证优先遍历左侧。

第一个栈的处理顺序为,自上而下,自右而左。经过第二个栈的逆序,就变成了自下而上,自左而右。

每次将新节点加入队列时,将nlast更新成新节点。

当当前打印的节点等于last,执行换行并将last更新到下一行nlast。

举个例子(用 ! 分割,用 # 表空):

将序列化字符串转化成数组(比如这里通过 ! 分割)

所以我们需要引入一个变量 setleft 来确定下一次需要构建的节点方向。

每次构建新节点之后,下一次都会尝试构建其左侧节点。

而每次遇到空节点后,都会将顶元素推出,并尝试构建其的右侧节点。

因为他的队列,只负责记录下一次想要处理的节点。

并不需要在意左右与层级倒退,只需要处理节点为空的情况即可。

如下图中第三棵二叉树。

2节点的子树下方,左侧高度为2,右侧高度为0。所以不是一个平衡二叉树。

一旦一侧子节点为空,另一侧若高度大于2,则判定为否

目的都是提高搜索二叉树的效率,调整代价降低。

第一个错误的节点为第一次降序较大的节点

第二个错误的节点为第二次降序较小的节点

第一个错误的节点为此次降序较大的节点

第二个错误的节点为此次降序较小的节点

除最后一层无任何子 节点 外,每一层上的所有结点都有两个子结点二叉树。

从图形形态上看,满二叉树外观上是一个三角形

这种满二叉树的层数为L,节点数为N。

则N = 2^L-1 ,L = log(N+1)

满二叉树的结点要么是叶子结点,度为0,要么是度为2的结点,不存在度为1的结点。

在满二叉树的基础上,最后一层所有的结点都连续集中在最左边,这就是完全二叉树。

先遍历左子树左边界,再遍历右子树左边界。从而判断哪边为满二叉树。

满二叉树侧,N=2^H。非满二叉树侧,递归。

每层只遍历一个节点的子树,总计LogN。

每个子树获取右子树左边界遍,需要经历LogN次计算。

总复杂度O((LogN^2))

如果从下标从1开始存储,则编号为i的结点的主要关系为:

双亲:下取整 (i/2)

左孩子:2i

右孩子:2i+1

如果从下标从0开始存储,则编号为i的结点的主要关系为:

双亲:下取整 ((i-1)/2)

左孩子:2i+1

右孩子:2i+2

2的后序节点为3,2的前驱节点为1

下图中2,1两节点距离为2。3,5节点距离为5

三个情况下最大的结果,就是以head为头节点的整棵树上最远的距离。

Swift 算法实战之路:二叉树

左神牛课网算法课