数据结构之判断平衡二叉树详解与示例(C,C++)
文章目录
- AVL树定义
- 节点定义
- 计算高度
- 获取平衡因子
- 判断是否为平衡二叉树
- 完整示例代码
- 结论

在计算机科学中,二叉树是一种非常重要的数据结构。它们被广泛用于多种算法中,如排序、查找等。然而,普通的二叉树在极端情况下可能退化成链表,导致算法性能大大降低。为了解决这个问题,Adelson-Velsky和Landis在1962年提出了平衡二叉树(AVL树)。本文将详细介绍如何判断一个二叉树是否为平衡二叉树,并提供C和C++语言的示例代码。
AVL树定义
AVL树是一种自平衡的二叉搜索树,其中任何节点的两个子树的高度最大差别为1。这种平衡保证了树的高度大约是log(n),其中n是树中节点的数量。这使得AVL树在最坏情况下的查找、插入和删除操作的时间复杂度都是O(log n)。
节点定义
首先,我们需要定义树的节点结构。每个节点包含以下信息:
- 键值(Key)
- 左子树指针(Left)
- 右子树指针(Right)
- 节点高度(Height)
C语言示例
struct TreeNode {int key;struct TreeNode *left;struct TreeNode *right;int height;
};
C++语言示例
struct TreeNode {int key;TreeNode *left;TreeNode *right;int height;TreeNode(int k) : key(k), left(nullptr), right(nullptr), height(1) {}
};
计算高度
计算节点的高度,如果节点为空,则高度为-1。
C语言示例
int height(struct TreeNode *N) {if (N == NULL)return 0;return N->height;
}
C++语言示例
int height(TreeNode *N) {if (N == nullptr) return 0;return N->height;
}
获取平衡因子
平衡因子是右子树高度与左子树高度的差。如果节点的平衡因子绝对值大于1,则该树不是平衡的。
C语言示例
int getBalance(struct TreeNode *N) {if (N == NULL)return 0;return height(N->right) - height(N->left);
}
C++语言示例
int getBalance(TreeNode *N) {if (N == nullptr) return 0;return height(N->right) - height(N->left);
}
判断是否为平衡二叉树
通过递归检查每个节点,判断是否每个节点的平衡因子都在-1到1之间。
C语言示例
int isBalanced(struct TreeNode *root) {if (root == NULL)return 1;int leftHeight = height(root->left);int rightHeight = height(root->right);if (abs(leftHeight - rightHeight) > 1)return 0;return isBalanced(root->left) && isBalanced(root->right);
}
C++语言示例
bool isBalanced(TreeNode *root) {if (root == nullptr) return true;int leftHeight = height(root->left);int rightHeight = height(root->right);if (abs(leftHeight - rightHeight) > 1)return false;return isBalanced(root->left) && isBalanced(root->right);
}
完整示例代码
以下是完整的示例代码,包括创建树和判断是否为平衡二叉树。
C语言完整示例
#include <stdio.h>
#include <stdlib.h>
#include <math.h>// ... (省略之前定义的TreeNode结构和函数)int main() {struct TreeNode *root = newNode(1);root->left = newNode(2);root->right = newNode(3);root->left->left = newNode(4);root->left->right = newNode(5);if (isBalanced(root))printf("Tree is balanced\n");elseprintf("Tree is not balanced\n");return 0;
}
C++语言完整示例
#include <iostream>
#include <cmath>
#include <algorithm>using namespace std;// ... (省略之前定义的TreeNode结构和函数)int main() {TreeNode *root = new TreeNode(1);root->left = new TreeNode(2);root->right = new TreeNode(3);root->left->left = new TreeNode(4);root->left->right = new TreeNode(5);if (isBalanced(root))cout << "Tree is balanced" << endl;elsecout << "Tree is not balanced" << endl;// 注意:在C++中,使用new分配的内存需要手动释放delete root->left->left;delete root->left->right;delete root->left;delete root->right;delete root;return 0;
}
完整示例代码(C语言)
递归检查每个节点,如果发现任何节点的平衡因子不在-1到1之间,则整棵树不是平衡二叉树。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>struct TreeNode {int key;struct TreeNode *left;struct TreeNode *right;int height;
};int max(int a, int b) {return (a > b) ? a : b;
}int height(struct TreeNode *N) {if (N == NULL)return 0;return N->height;
}int getBalance(struct TreeNode *N) {if (N == NULL)return 0;return height(N->right) - height(N->left);
}struct TreeNode *newNode(int key) {struct TreeNode *node = (struct TreeNode *)malloc(sizeof(struct TreeNode));node->key = key;node->left = NULL;node->right = NULL;node->height = 1; // 新节点被当做叶子节点加入,高度为1return(node);
}int isBalanced(struct TreeNode *root) {if (root == NULL)return 1;int leftHeight = height(root->left);int rightHeight = height(root->right);if (abs(leftHeight - rightHeight) > 1)return 0;return isBalanced(root->left) && isBalanced(root->right);
}int main() {struct TreeNode *root = newNode(1);root->left = newNode(2);root->right = newNode(3);root->left->left = newNode(4);root->left->right = newNode(5);if (isBalanced(root))printf("Tree is balanced\n");elseprintf("Tree is not balanced\n");return 0;
}
此代码将创建一个简单的二叉树,并检查它是否为平衡二叉树。在实际应用中,平衡二叉树的插入和删除操作会更复杂,因为它们需要维护树的平衡,通常会涉及到节点的旋转操作。
结论
本文详细介绍了如何判断一个二叉树是否为平衡二叉树,并提供了C和C++语言的示例代码。在实际应用中,平衡二叉树的插入和删除操作会更复杂,因为它们需要维护树的平衡,通常会涉及到节点的旋转操作。理解并掌握AVL树是成为一名优秀程序员的重要一步,因为它不仅能够提高算法的效率,还能帮助我们在处理复杂问题时保持清晰的逻辑思维。
相关文章:

数据结构之判断平衡二叉树详解与示例(C,C++)
文章目录 AVL树定义节点定义计算高度获取平衡因子判断是否为平衡二叉树完整示例代码结论 在计算机科学中,二叉树是一种非常重要的数据结构。它们被广泛用于多种算法中,如排序、查找等。然而,普通的二叉树在极端情况下可能退化成链表ÿ…...
深入解析仓颉编程语言:函数式编程的核心特性
摘要 仓颉编程语言以其独特的语法和功能,为开发者提供了强大的编程工具。本文将深入探讨仓颉语言中的嵌套函数、Lambda 表达式和闭包等函数式编程的核心特性,帮助开发者更好地理解和利用这些工具。 引言 在现代编程语言中,函数式编程范式越…...

springboot惠农服务平台-计算机毕业设计源码50601
目录 1 绪论 1.1 研究背景 1.2研究意义 1.3论文结构与章节安排 2 惠农服务平台app 系统分析 2.1 可行性分析 2.2 系统功能分析 2.3 系统用例分析 2.4 系统流程分析 2.5本章小结 3 惠农服务平台app 总体设计 3.1 系统功能模块设计 3.2 数据库设计 表access_token (…...

Lua脚本简单理解
目录 1.安装 2.语法 2.1Lua数据类型 2.2变量 2.3lua循环 2.4流程控制 2.5函数 2.6运算符 2.7关系运算符 3.lua脚本在redis中的使用 3.1lua脚本再redis简单编写 3.2普通锁Lua脚本 3.3可重入锁lua脚本 1.安装 centos安装 安装指令: yum -y update yum i…...
AutoSAR自适应平台架构总览--AP的初认识
AutoSAR自适应平台架构总览:AP 基础设施层(Foundation Layer)核心操作系统(Core OS)通信管理(Communication Management) 服务层(Services Layer)诊断服务(Diagnostics S…...

GPT-4o Mini:探索最具成本效益的小模型在软件开发中的应用
随着人工智能技术的迅猛发展,自然语言处理(NLP)领域也取得了显著的进步。OpenAI 最新发布的 GPT-4o Mini 模型,以其卓越的性能和极具竞争力的价格,成为了广大开发者关注的焦点。作为一名长期关注人工智能及其在软件开发…...

{Spring Boot 原理篇} Spring Boot自动装配原理
SpringBootApplication 1,Spring Boot 应用启动,SpringBootApplication标注的类就是启动类,它去实现配置类中的Bean的自动装配 SpringBootApplication public class SpringbootRedis01Application {public static void main(String[] args)…...

QEMU源码全解析 —— CPU虚拟化(10)
接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 二、x86架构CPU虚拟化 3. VMX 上一回讲解了支…...
46、PHP实现矩阵中的路径
题目: PHP实现矩阵中的路径 描述: 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。 路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向…...

c++笔记2
目录 2.2 栈底(bottom) } 大数乘大数 节点:包含一个数据元素及若干指向子树分支的信息 。 节点的度:一个节点拥有子树的数目称为节点的度 。 叶子节点:也称为终端节点,没有子树的节点或者度为零的节点…...
通过Lua脚本手写redis分布式锁
1、手写 Redis 分布式锁,包括上锁、解锁、自动续期。 此功能实现采用 Lua脚本实现,Lua脚本可以保证原子性。 setnx可以实现分布式锁,但是无法实现可重入锁,所以用hset来代替setnx实现可重入的分布式锁。 -- lock if redis.call…...
解析银行个人征信系统
银行个人征信系统,也被称为个人信用信息基础数据库或金融信用信息基础数据库,是我国社会信用体系的重要基础设施。该系统由中国人民银行组织国内相关金融机构建立,旨在依法采集、整理、保存、加工自然人(法人)及其他组…...

AttributeError: ‘list‘ object has no attribute ‘text‘
AttributeError: ‘list‘ object has no attribute ‘text‘ 目录 AttributeError: ‘list‘ object has no attribute ‘text‘ 【常见模块错误】 【解决方案】 示例代码 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英…...

Codeforces Round 874 (Div. 3)(A~D题)
A. Musical Puzzle 思路: 用最少的长度为2的字符串按一定规则拼出s。规则是:前一个字符串的尾与后一个字符串的首相同。统计s中长度为2的不同字符串数量。 代码: #include<bits/stdc.h> #include <unordered_map> using namespace std; #define N 20…...
[Python][基础语法]详细讲解
目录 1.顺序语句2.条件语句3.缩进和代码块4.空语句 pass5.循环语句1.while2.for3.continue4.break ∞.积累 1.顺序语句 默认情况下,Python的代码执行顺序是按照从上到下的顺序,依次执行# 输出结果:"123" print("1") pri…...
Layui---输入事件
输入实时监听 //监听表单单选框复选框选择 form.on(radio, function (data) {console.log(data.value); //得到被选中的值 });//监听表单下拉菜单选择form.on(select, function (data) //监听表单下拉菜单选择form.on(select, function (data) //监听表单复选框选择form.…...

甄选范文“论软件测试中缺陷管理及其应用”软考高级论文,系统架构设计师论文
论文真题 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误,或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中,缺陷是不可避免的。软件测试是发现缺陷的主要手段,其核心目标就是尽可能多地找…...
spring框架实现滑动验证码功能
spring框架实现滑动验证码功能 1. 整体描述2. 具体实现2.1 滑动验证码实体类2.2 滑动验证码登录VO2.3 滑动验证码接口返回类2.4 滑动验证码工具类2.5 滑动验证码Service2.6 滑动验证码Controller 3 工程源码4 总结 1. 整体描述 之前项目需要在验证码模块,增加滑动验…...

Pytorch使用教学8-张量的科学运算
在介绍完PyTorch中的广播运算后,继续为大家介绍PyTorch的内置数学运算: 首先对内置函数有一个功能印象,知道它的存在,使用时再查具体怎么用其次,我还会介绍PyTorch科学运算的注意事项与一些实用小技巧 1 基本数学运算…...
[Spring Boot]登录密码三种加密方式
简述 介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1,其次使用方法2,最不推荐的是方法3。方法3极其容易被密码字典破解,如果项目进行安全测试,通常是不允许的加密方式。 SM2加密与验签 引入…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...