数据结构之判断平衡二叉树详解与示例(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加密与验签 引入…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...