一句话说透数据结构里面的二叉树的层序遍历

157 阅读2分钟

一句话总结:
二叉树的层序遍历就像剥洋葱——一层一层剥开,每层从左到右处理节点,用队列来维护“待处理队伍”!


一、层序遍历原理

核心思想:  使用队列(FIFO)依次处理每一层节点:

  1. 根节点入队

  2. 循环处理队列中的节点,每次处理一层:

    • 记录当前层的节点数量
    • 依次出队节点,将其子节点入队
  3. 收集每层的节点值


二、Kotlin 代码实现

// 定义二叉树节点
class TreeNode(var value: Int) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

fun levelOrder(root: TreeNode?): List<List<Int>> {
    val result = mutableListOf<List<Int>>()
    if (root == null) return result

    val queue = ArrayDeque<TreeNode>()
    queue.add(root) // 根节点入队

    while (queue.isNotEmpty()) {
        val levelSize = queue.size // 当前层的节点数
        val currentLevel = mutableListOf<Int>()

        repeat(levelSize) { // 处理当前层所有节点
            val node = queue.removeFirst()
            currentLevel.add(node.value)
            // 子节点入队(下一层)
            node.left?.let { queue.add(it) }
            node.right?.let { queue.add(it) }
        }

        result.add(currentLevel)
    }

    return result
}

三、测试用例

fun main() {
    // 测试用例1:普通二叉树
    //       3
    //      / \
    //     9  20
    //       /  \
    //      15   7
    val root1 = TreeNode(3).apply {
        left = TreeNode(9)
        right = TreeNode(20).apply {
            left = TreeNode(15)
            right = TreeNode(7)
        }
    }
    println(levelOrder(root1)) // 输出 [[3], [9,20], [15,7]]

    // 测试用例2:空树
    println(levelOrder(null)) // 输出 []

    // 测试用例3:单节点树
    val root3 = TreeNode(1)
    println(levelOrder(root3)) // 输出 [[1]]

    // 测试用例4:只有左子树
    //       1
    //      /
    //     2
    //    /
    //   3
    val root4 = TreeNode(1).apply {
        left = TreeNode(2).apply {
            left = TreeNode(3)
        }
    }
    println(levelOrder(root4)) // 输出 [[1], [2], [3]]
}

四、复杂度分析

操作时间复杂度空间复杂度说明
层序遍历O(n)O(n)n为节点数,队列最大存储最后一层节点(约n/2)

五、分步图解(以测试用例1为例)

初始队列:[3]  
第1层处理:  
   取出3 → 收集[3]  
   子节点920入队 → 队列[9,20]  
结果:[[3]]2层处理:  
   队列大小=2 → 处理两次  
   取出9 → 收集[9],无子节点  
   取出20 → 收集[20],子节点157入队 → 队列[15,7]  
结果:[[3], [9,20]]3层处理:  
   队列大小=2 → 处理两次  
   取出15 → 收集[15],无子节点  
   取出7 → 收集[7],无子节点  
结果:[[3], [9,20], [15,7]]  

六、应用场景

  1. 按层级打印树结构
  2. 寻找每层最大值/平均值(如LeetCode 102、637题)
  3. 判断完全二叉树(层序遍历中不应出现空节点后还有非空节点)

口诀:
层序遍历用队列,
一层一波按顺序。
左子右子依次进,
剥完洋葱就收工!