news 2026/4/16 13:25:55

算法题 二叉树的完全性检验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法题 二叉树的完全性检验

二叉树的完全性检验

问题描述

给定一个二叉树的根节点root,判断该二叉树是否为完全二叉树

完全二叉树定义
在完全二叉树中,除了最底层外,其他层都被完全填满,并且所有结点都尽可能地向左集中。最底层的结点可以不满,但必须从左到右连续排列,不能有“空洞”。

示例

输入: [1,2,3,4,5,6] 输出: true 解释: 所有层都被完全填满,是完全二叉树。 输入: [1,2,3,4,5,null,7] 输出: false 解释: 最底层右边有空洞(6的位置为空,但7存在),不是完全二叉树。

算法思路

层序遍历(BFS)

  1. 使用队列进行层序遍历
  2. 遇到第一个null节点后,后续所有节点都必须是null
  3. 如果在遇到null后又遇到非null节点,说明存在空洞,不是完全二叉树

代码实现

方法一:层序遍历

importjava.util.*;/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */classSolution{/** * 判断二叉树是否为完全二叉树 * * @param root 二叉树根节点 * @return 如果是完全二叉树返回true,否则返回false */publicbooleanisCompleteTree(TreeNoderoot){if(root==null){returntrue;}Queue<TreeNode>queue=newLinkedList<>();queue.offer(root);booleanfoundNull=false;// 标记是否遇到了第一个null节点while(!queue.isEmpty()){TreeNodenode=queue.poll();if(node==null){// 遇到null节点,标记为已发现nullfoundNull=true;}else{// 如果之前已经遇到过null,现在又遇到非null节点// 说明存在空洞,不是完全二叉树if(foundNull){returnfalse;}// 将左右子节点加入队列(包括null节点)queue.offer(node.left);queue.offer(node.right);}}returntrue;}}

方法二:节点编号

importjava.util.*;classSolution{/** * 基于节点编号验证完全二叉树 * 完全二叉树按层序遍历编号时,节点编号应该是连续的1,2,3,...,n * * @param root 二叉树根节点 * @return 如果是完全二叉树返回true,否则返回false */publicbooleanisCompleteTree(TreeNoderoot){if(root==null){returntrue;}Queue<TreeNode>queue=newLinkedList<>();Queue<Integer>indices=newLinkedList<>();// 存储对应节点的编号queue.offer(root);indices.offer(1);// 根节点编号为1intcount=0;// 实际节点数量intlastIdx=0;// 最后一个节点的编号while(!queue.isEmpty()){TreeNodenode=queue.poll();intidx=indices.poll();count++;lastIdx=idx;if(node.left!=null){queue.offer(node.left);indices.offer(idx*2);// 左子节点编号为父节点编号*2}if(node.right!=null){queue.offer(node.right);indices.offer(idx*2+1);// 右子节点编号为父节点编号*2+1}}// 如果是完全二叉树,最后一个节点的编号应该等于总节点数returnlastIdx==count;}}

算法分析

  • 时间复杂度:O(n)
    • 两种方法都需要遍历所有节点一次
  • 空间复杂度:O(w)
    • w 为二叉树的最大宽度,最坏情况下为 O(n)(完全二叉树最后一层)

算法过程

输入[1,2,3,4,5,null,7]

方法一:

  1. 队列初始:[1]foundNull = false
  2. 处理节点1:加入子节点[2,3]foundNull = false
  3. 处理节点2:加入子节点[4,5],队列变为[3,4,5]
  4. 处理节点3:加入子节点[null,7],队列变为[4,5,null,7]
  5. 处理节点4:加入子节点[null,null],队列变为[5,null,7,null,null]
  6. 处理节点5:加入子节点[null,null],队列变为[null,7,null,null,null,null]
  7. 处理nullfoundNull = true
  8. 处理节点7:此时foundNull = true且遇到非null节点,返回false

方法二:

  1. 节点1:编号1,count=1,lastIdx=1
  2. 节点2:编号2,count=2,lastIdx=2
  3. 节点3:编号3,count=3,lastIdx=3
  4. 节点4:编号4,count=4,lastIdx=4
  5. 节点5:编号5,count=5,lastIdx=5
  6. 节点7:编号7,count=6,lastIdx=7
  7. 验证:lastIdx(7) != count(6),返回false

测试用例

publicclassTestCompleteBinaryTree{// 构建测试用的二叉树工具方法privatestaticTreeNodebuildTree(Integer[]arr){if(arr==null||arr.length==0||arr[0]==null){returnnull;}TreeNoderoot=newTreeNode(arr[0]);Queue<TreeNode>queue=newLinkedList<>();queue.offer(root);inti=1;while(!queue.isEmpty()&&i<arr.length){TreeNodenode=queue.poll();if(i<arr.length&&arr[i]!=null){node.left=newTreeNode(arr[i]);queue.offer(node.left);}i++;if(i<arr.length&&arr[i]!=null){node.right=newTreeNode(arr[i]);queue.offer(node.right);}i++;}returnroot;}publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:完全二叉树Integer[]tree1={1,2,3,4,5,6};System.out.println("Test 1: "+solution.isCompleteTree(buildTree(tree1)));// true// 测试用例2:非完全二叉树(有空洞)Integer[]tree2={1,2,3,4,5,null,7};System.out.println("Test 2: "+solution.isCompleteTree(buildTree(tree2)));// false// 测试用例3:单节点Integer[]tree3={1};System.out.println("Test 3: "+solution.isCompleteTree(buildTree(tree3)));// true// 测试用例4:只有左子树Integer[]tree4={1,2,null,4,5};System.out.println("Test 4: "+solution.isCompleteTree(buildTree(tree4)));// false// 测试用例5:满二叉树Integer[]tree5={1,2,3,4,5,6,7};System.out.println("Test 5: "+solution.isCompleteTree(buildTree(tree5)));// true// 测试用例6:空树Integer[]tree6={};System.out.println("Test 6: "+solution.isCompleteTree(buildTree(tree6)));// true// 测试用例7:只有右子树Integer[]tree7={1,null,3,null,7};System.out.println("Test 7: "+solution.isCompleteTree(buildTree(tree7)));// false}}

关键点

  1. 完全二叉树

    • 层序遍历中不能有"空洞"
    • 一旦出现null,后续必须全部为null
  2. 层序遍历

    • 必须按层从左到右遍历
    • 需要将null节点也加入队列进行处理
  3. 边界情况处理

    • 空树被认为是完全二叉树
    • 单节点树是完全二叉树
    • 只有左子树的树可能是完全二叉树,只有右子树的一定不是

常见问题

  1. 为什么需要将 null 节点加入队列?

    • 为了检测空洞,必须知道在什么位置出现了 null,以及 null 之后是否还有非 null 节点。
  2. 完全二叉树和满二叉树的区别?

    • 满二叉树:所有层都完全填满
    • 完全二叉树:除最后一层外都填满,最后一层从左到右连续
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 21:24:06

Qwen-Image-2512-ComfyUI文旅宣传应用:景区海报自动生成系统

Qwen-Image-2512-ComfyUI文旅宣传应用&#xff1a;景区海报自动生成系统 1. 让景区宣传更高效&#xff1a;AI如何改变文旅内容创作 你有没有遇到过这样的情况&#xff1f;旅游旺季临近&#xff0c;宣传物料却还在等设计师加班出图&#xff1b;一个景区有十几个打卡点&#xf…

作者头像 李华
网站建设 2026/4/5 19:39:01

Z-Image-Turbo支持哪些格式?PNG转换技巧分享

Z-Image-Turbo支持哪些格式&#xff1f;PNG转换技巧分享 1. Z-Image-Turbo图像生成与输出格式详解 阿里通义Z-Image-Turbo WebUI图像快速生成模型&#xff0c;由社区开发者“科哥”基于DiffSynth Studio框架进行二次开发构建&#xff0c;是一款专注于高效、高质量AI图像生成的…

作者头像 李华
网站建设 2026/4/7 2:40:56

unet image Face Fusion跨域问题解决?CORS配置正确姿势

unet image Face Fusion跨域问题解决&#xff1f;CORS配置正确姿势 1. 背景与问题引入 在部署基于 unet image Face Fusion 的人脸融合 WebUI 应用时&#xff0c;很多开发者会遇到一个看似简单却极具迷惑性的问题&#xff1a;前端页面能正常加载&#xff0c;但图片上传或融合…

作者头像 李华
网站建设 2026/4/15 22:24:42

学生党如何跑动GPEN?低配GPU显存优化实战技巧

学生党如何跑动GPEN&#xff1f;低配GPU显存优化实战技巧 你是不是也遇到过这种情况&#xff1a;看到一个超厉害的人像修复AI模型&#xff0c;兴冲冲下载下来&#xff0c;结果一运行就爆显存&#xff0c;GPU直接卡死&#xff1f;别急&#xff0c;这不怪你电脑不行&#xff0c;…

作者头像 李华
网站建设 2026/4/13 23:52:34

Qwen3-1.7B跨境电商应用:多语言商品描述生成

Qwen3-1.7B跨境电商应用&#xff1a;多语言商品描述生成 1. Qwen3-1.7B 模型简介 Qwen3&#xff08;千问3&#xff09;是阿里巴巴集团于2025年4月29日开源的新一代通义千问大语言模型系列&#xff0c;涵盖6款密集模型和2款混合专家&#xff08;MoE&#xff09;架构模型&#…

作者头像 李华