使用LeetCode方式初始化二叉树

前言

Google 2017 I/O大会上,Google将Android开发的官方语言更换为Kotlin,作为一个安卓开发者,你怎么能说自己不会kotlin呢?那不如就从LeetCode开始吧!毕竟写代码才是开发路上的唯一捷径。

深度优先搜索

深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。

本博客准备以深度优先搜索入手,结合kotlin语法,对LeetCode的一些习题进行由浅入深的学习。

二叉树的初始化

在LeetCode中,官方给出了一个初始化二叉树的类定义如下:

class TreeNode(var `val`: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

于是我们想要验证自己写的习题的时候成了这个样子来自力扣98题:

private fun test98() {
    val root = TreeNode(5)
    root.left = TreeNode(1)
    root.right = TreeNode(4)
    root.right!!.left = TreeNode(3)
    root.right!!.right = TreeNode(6)
    println(isValidBST(root))
}

可是官方的输入示例完全不是这个画风啊,官方:


image.png

如果我能像官方那样直接输入下面的一串就能初始化二叉树那岂不是美滋滋?

5,1,4,null,null,3,6

根据我持续的观察,发现官方给出的二叉树输入是根据二叉树的层序遍历来实现的,并且省略了末尾多余的null值,咦,这题我会,使用一个队列就能很简单的实现二叉树的层序遍历了,二叉树的构造代码如下:

class TreeNode(var `val`: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null

    constructor(v0: Int, vararg v: Int?) : this(v0) {
        val queue = LinkedList()
        var index = -1
        queue.offer(this)
        while (queue.isNotEmpty()) {
            val size = queue.size
            for (i in 0 until size) {
                val temp = queue.pop()
                if (temp != null) {
                    index++
                    if (index < v.size && v[index] != null) {
                        temp.left = TreeNode(v[index]!!)
                    }
                    index++
                    if (index < v.size && v[index] != null) {
                        temp.right = TreeNode(v[index]!!)
                    }
                    queue.offer(temp.left)
                    queue.offer(temp.right)
                }
            }
        }
    }
}

使用如下:

TreeNode(1, 2, 2, null, 3, null, 3)

代码解释#入参

首先为了支持多个参数初始化二叉树,所以使用了vararg关键字来生命入参,为了保证参数个数至少存在一个,在前面加上一个v0,一个二叉树总得有一个val是吧,当然,这个入参就很自然的继承了默认构造方法TreeNode(var val: Int)(在kotlin中,所有的子构造函数都必须直接或间接的继承父构造器,不清楚的同学可以看看kotlin语法基础教程,里面有很详细的解释)

代码解释#初始化子节点

因为官方给的数据是层序遍历遍历得来的,所以很自然的就想到了使用队列来实现程序遍历,我们只需保证每次遍历,遍历完一层,并将第一层移出队列,然后输入第二层进队列,就能保证层序遍历的顺序了,具体流程如下图:

image.png

如此就能保证按照层的顺序遍历整个二叉树了。
是不是能帮你省下不少测试代码的时间呢,反正帮我省了不少哈哈哈哈。
如果你使用的是gradle构建工程,可以直接引入我的LeetCode项目代码。

你可能感兴趣的:(使用LeetCode方式初始化二叉树)