美文网首页
二叉树的遍历(Kotlin)

二叉树的遍历(Kotlin)

作者: czins | 来源:发表于2017-02-28 01:15 被阅读79次
package com.colbert.binarytree

import com.sun.jmx.remote.internal.ArrayQueue
import java.util.*

class BinaryTree(var rootNode: TreeNode = BinaryTree.TreeNode(1, "A")) {

    class TreeNode {
        var index: Int
        var data: String
        var leftChild: TreeNode?
        var rightChild: TreeNode?

        constructor(index: Int, data: String) {
            this.index = index
            this.data = data
            this.leftChild = null
            this.rightChild = null
        }
    }

    /**
     * 构建二叉树
     *             A
     *       B          C
     *  D        E F         G
     */
    fun createBinaryTree() {
        var nodeB = TreeNode(2, "B")
        var nodeC = TreeNode(3, "C")
        var nodeD = TreeNode(4, "D")
        var nodeE = TreeNode(5, "E")
        var nodeF = TreeNode(6, "F")
        var nodeG = TreeNode(6, "G")
        rootNode.leftChild = nodeB;
        rootNode.rightChild = nodeC
        nodeB.leftChild = nodeD
        nodeB.rightChild = nodeE
        nodeC.leftChild = nodeF
        nodeC.rightChild = nodeG
    }

    /**
     * 树的高度
     */
    fun getHeight(): Int {
        return getHeight(rootNode);
    }

    fun getHeight(node: TreeNode?): Int {
        if (node == null) {
            return 0
        } else {
            return Math.max(getHeight(node?.leftChild), getHeight(node?.rightChild)) + 1
        }
    }

    /**
     * 树的节点数
     */
    fun getSize(): Int {
        return getSize(rootNode)
    }

    fun getSize(node: TreeNode?): Int {
        if (node == null) {
            return 0
        } else {
            // 父节点(1) + 左节点 + 右节点
            return getSize(node?.leftChild) + getSize(node?.rightChild) + 1
        }
    }

    /**
     * 前序遍历
     * 顺序:先遍历根节点,再遍历左子节点,最后遍历右子节点
     */
    fun preOrder() {
        preOrder(rootNode)
    }

    fun preOrder(node: TreeNode?) {
        if (node == null) return
        print(node?.data + " ")
        preOrder(node?.leftChild)
        preOrder(node?.rightChild)
    }

    /**
     * 前序遍历
     * 非迭代实现 (栈)
     */
    fun stackPreOrder() {
        if (rootNode == null) return
        var stack: Stack<TreeNode> = Stack()
        stack.push(rootNode)
        do {
            var node: TreeNode = stack.pop()
            print(node.data + " ")
            if (node.rightChild != null) {
                stack.push(node.rightChild)
            }
            if (node.leftChild != null) {
                stack.push(node.leftChild)
            }
        } while (!stack.isEmpty())
    }

    /**
     * 中序遍历
     * 顺序:先遍历左子节点,再遍历根节点,最后遍历右子节点
     */
    fun midOrder() {
        midOrder(rootNode)
    }

    fun midOrder(node: TreeNode?) {
        if (node == null) return
        midOrder(node?.leftChild)
        print(node?.data + " ")
        midOrder(node?.rightChild)
    }

    /**
     * 中序遍历
     * 非迭代实现 (栈)
     */
    fun stackMidOrder() {
        if (rootNode == null) return
        var stack: Stack<TreeNode> = Stack()
        var node: TreeNode? = rootNode
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node)
                node = node?.leftChild
            }
            node = stack.pop()
            print(node?.data + " ")
            node = node?.rightChild
        }
    }

    /**
     * 后序遍历
     * 顺序:先遍历左子节点,再遍历右子节点,最后遍历根节点
     */
    fun afterOrder() {
        afterOrder(rootNode)
    }

    fun afterOrder(node: TreeNode?) {
        if (node == null) return
        afterOrder(node?.leftChild)
        afterOrder(node?.rightChild)
        print(node?.data + " ")
    }

    /**
     * 后序遍历
     * 非迭代实现 (栈)
     */
    fun stackAfterOrder() {
        if (rootNode == null) return
        var node: TreeNode? = rootNode
        var stack: Stack<TreeNode?> = Stack()
        // 存放右节点是否被访问过
        var map = HashMap<TreeNode?, Boolean>();
        while (node != null || stack.isNotEmpty()) {
            while (node != null) {
                stack.push(node)
                node = node?.leftChild
            }
            node = stack.peek()
            if (map.getOrDefault(node, false)) {
                // 如果右节点被访问过,就打印出来,并把它弹出栈
                print(node?.data + " ")
                map.remove(stack.pop())
                node = null
            } else {
                map.put(node, true)
                node = node?.rightChild
            }
        }
    }

    /**
     * 层序遍历 (队列)
     * 顺序:按层次依次遍历树的节点
     */
    fun queueLevelOrder() {
        if (rootNode == null) return
        var queue = ArrayDeque<TreeNode>()
        queue.offer(rootNode)
        while (queue.isNotEmpty()) {
            // 将对头的元素弹出队列
            var node = queue.poll()
            print(node?.data + " ")
            if (node?.leftChild != null) {
                // 将左节点加入到对尾
                queue.offer(node?.leftChild)
            }
            if (node?.rightChild != null) {
                // 将右节点加入到对尾
                queue.offer(node?.rightChild)
            }
        }
    }
}

fun main(args: Array<String>) {
    var tree = BinaryTree()
    tree.createBinaryTree()

    // 树的高度
    print("树的高度 " + tree.getHeight())
    // 树的节点数
    print("\n树的节点数 " + tree.getSize())
    // 前序遍历
    print("\n前序遍历 ")
    tree.preOrder()
    // 前序栈遍历
    print("\n前序栈遍历 ")
    tree.stackPreOrder()
    // 中序遍历
    print("\n中序遍历 ")
    tree.midOrder()
    // 中序栈遍历
    print("\n中序栈遍历 ")
    tree.stackMidOrder()
    // 后序遍历
    print("\n后序遍历 ")
    tree.afterOrder()
    print("\n后序栈遍历 ")
    tree.stackAfterOrder()
    // 层序遍历
    print("\n层序遍历 ")
    tree.queueLevelOrder()
}

相关文章

  • 二叉树 基础操作

    二叉树的使用 二叉树结构 先序创建二叉树 DFS 先序遍历二叉树 中序遍历二叉树 后序遍历二叉树 BFS 层次遍历...

  • 二叉树遍历

    二叉树 二叉树的存储结构 前序遍历 中序遍历 后序遍历 遍历代码 反转二叉树 深入学习二叉树 二叉树-你必须要懂!...

  • 二叉树操作

    树节点 逐行顺序解析二叉树 前序遍历二叉树 中序遍历二叉树 后序遍历二叉树 删除指定数值的节点 前序遍历顺序存储的...

  • 关于二叉树的算法题

    前序遍历中序遍历后序遍历判断是否是平衡二叉树判断是否是对称二叉树判断二叉树高度按照层遍历二叉树判断二叉树宽度

  • 二叉树三种遍历Swift代码实现

    二叉树的三种遍历 二叉树 前序遍历 中序遍历 后序遍历 另外 不得不说,得到二叉树的前序遍历和中序遍历的结果或者后...

  • 数据结构与算法之二叉树遍历(七)

    目录 前序遍历中序遍历后序遍历层序遍历遍历方式的选择条件根据遍历结果重构二叉树翻转二叉树计算二叉树的高度判断一棵树...

  • 二叉树的遍历

    二叉树的遍历 二叉树遍历 分为前序遍历、中序遍历和后序遍历。 前序遍历 (DLR) 先访问根节点,然后前序遍历左子...

  • 数据结构:树的实现和遍历(c++)

    (一)二叉树的遍历——递归实现 二叉树常见的遍历方式分为前序遍历、中序遍历和后序遍历。 1 前序遍历 前序遍历也叫...

  • 二叉树的蛇形层次遍历(LeetCode.103)

    题目 解析 首先参考二叉树的层次遍历层次遍历二叉树(LeetCode--102二叉树的层次遍历)[https://...

  • Kotlin 链式存储的二叉树的创建、遍历

    本例中节点权结构图 遍历代码运行结果图 1. Kotlin 中二叉树的创建 简单二叉树的创建分为三部分: 新建节点...

网友评论

      本文标题:二叉树的遍历(Kotlin)

      本文链接:https://www.haomeiwen.com/subject/nvntgttx.html