C-数据结构-平横二叉树
平衡二叉树(Balanced Binary Tree)是一种二叉树,其中任意节点的两棵子树的高度差不超过 1。也可以说是一棵空树或者左右子树高度差不超过 1 的二叉树。
特点和性质
- 高度平衡:平衡二叉树是一种高度平衡的二叉树,任意节点的左右子树高度差不超过 1。
- 高度复杂度:由于平衡性质,平衡二叉树的高度复杂度为 O(log n),其中 n 是树中节点的数量。
- 插入和删除操作效率高:由于平衡性质,插入和删除操作的平均时间复杂度也是 O(log n)。
- 查找操作效率高:在平衡二叉树中查找元素的时间复杂度也是 O(log n)。
- 常见实现:AVL 树和红黑树是常见的平衡二叉树实现。
平衡因子
在平衡二叉树中,每个节点的平衡因子是其左子树高度和右子树高度之差。平衡因子的取值范围通常为 {-1, 0, 1},表示左右子树的高度差为 -1、0 或 1。
平衡操作
当向平衡二叉树中插入或删除节点时,可能会破坏树的平衡性质,此时需要通过旋转操作来恢复平衡。常见的旋转操作包括左旋和右旋,以及它们的组合操作。
应用
平衡二叉树广泛用于需要高效的插入、删除和查找操作的场景,例如数据库索引、缓存实现等。
‘’’
下面代码实现了二叉树的平衡
以及删除 查找 4种遍历 draw
‘’’
main.c
#include<stdio.h>
#include<stdlib.h>#include<queue.h> //已经被封装成动态库#define NAMESIZE 32struct score_st
{int id;char name[NAMESIZE];int math;int chinese;
};struct node_st
{struct score_st data;struct node_st *l,*r;
};static struct node_st *tree = NULL;//把tree提升到全局变量,当前文件static void print_s(struct score_st *d)
{printf("%d %s %d %d\n",d->id,d->name,d->math,d->chinese);
}int insert(struct node_st **root,struct score_st *data)
{struct node_st *node;if(*root == NULL){node = malloc(sizeof(*node));if(node == NULL)return -1;node->data = *data;node->l = NULL;node->r = NULL;*root = node;return 0;}if(data->id <= (*root)->data.id)return insert(&(*root)->l,data);elsereturn insert(&(*root)->r,data);
}
struct score_st *find(struct node_st *root,int id)
{if(root == NULL)return NULL;if(id == root->data.id)return &root->data;if(id < root->data.id)return find(root->l,id);elsereturn find(root->r,id);
}
void draw_(struct node_st *root,int level)
{int i;if(root == NULL)return ;draw_(root->r,level+1);for(i = 0;i<level;i++)printf(" ");print_s(&root->data);draw_(root->l,level+1);
}
void draw(struct node_st *root)
{draw_(root,0);printf("\n\n");//getchar();//相当于暂停
}static int get_num(struct node_st *root)
{if(root == NULL)return 0;return get_num(root->l) +1 +get_num(root->r);}static struct node_st *find_min(struct node_st *root)
{if(root->l == NULL)return root;return find_min(root->l);
}static void turn_left(struct node_st **root)
{struct node_st *cur = *root;*root = cur->r;cur->r = NULL;find_min(*root)->l = cur;//draw(tree);//测试语句
}static struct node_st *find_max(struct node_st *root)
{if(root->r == NULL)return root;return find_max(root->l);
}static void turn_right(struct node_st **root)
{struct node_st *cur = *root;*root = cur->l;cur->l = NULL;find_max(*root)->r = cur;//draw(tree);//测试语句
}void balance(struct node_st **root)//函数实现 先把伪代码写出来 ,梳理清楚整个的逻辑关系
{int sub;if(*root == NULL)return ;while(1){sub = get_num((*root)->l) -get_num((*root)->r);if(sub >= -1 && sub <=1)break;if(sub < -1)turn_left(root);elseturn_right(root);}balance(&(*root)->l);balance(&(*root)->r);
}void detele(struct node_st **root,int id)//删除一个节点 左边顶上来
{struct node_st **node = root;struct node_st *cur = NULL;while(*node != NULL && (*node)->data.id != id){if(id < ((*node)->data.id))&node = (*node)->l;else&node = (*node)->r;}if(*node == NULL)return ;cur = *node;if(cur->l == NULL)*node = cur->r;else{*node = cur->l;find_max(cur->l)->r = cur->r;}free(cur);
}#if 0
void travel(struct node_st *root)//先序遍历 根 左 右 中序遍历 左 根 右 后序遍历 后序遍历 左 右 根
{if(root == NULL)return ;print_s(&root->data);//travel(root->l); //travel(root->l);travel(root->l); //print_s(&root->data); //travel(root->r);travel(root->r); //travel(root->r); //print_s(&root->data)
}
#elsevoid travel(struct node_st *root)//借助之前封装好的queue库
{int ret;QUEUE *qu;struct node_st *cur;qu = queue_create(sizeof(struct node_st *));if(qu == NULL)return ;queue_en(qu,&root);/*if error*/while(1){ret = queue_de(qu,&cur);if(ret == -1)break;print_s(&cur->data);if(cur->l !=NULL)queue_en(qu,&cur->l);if(cur->r !=NULL)queue_en(qu,&cur->r);}queue_deatroy(qu);
}#endifint main()
{int arr[] = {1,2,3,7,6,5,9,8,4};int i;struct score_st tmp,*datap;struct node_st *tree = NULL;for(i = 0;i<sizeof(arr)/sizeof(*arr);i++){tmp.id = arr[i];snprintf(tmp.name,NAMESIZE,"stu%d",arr[i]);tmp.math = rand()%100;tmp.chinese = rand()%100;insert(&tree,&tmp);}draw(tree);balance(&tree);draw(tree);travel(tree);#if 0 int tmpid = 5;delete(&tree,tmpid);draw(tree);
#endif#if 0
//测试语句int tmpid = 2;datap = find(tree,tmpid);if(datap == NULL)printf("can not find the id %d\n",tmpid);elseprint_s(datap);
#endifexit(0);
}
gcc main.c -lqueue -lllist -o main
./main
补充说明
对于 这样的函数参数 struct node_st **root
您的理解基本上是正确的,但是有一个小的修正。让我详细解释一下:
*root是指向struct node_st *类型的指针。它存储了一个指向struct node_st类型的指针的地址。- 因此,
**root是一个struct node_st类型的结构体,因为它解引用了*root,得到了一个指向struct node_st类型的指针,然后再次解引用这个指针,得到了struct node_st类型的实际结构体。
因此,root 是一个指向指针的指针,可以用来修改指针指向的内容,从而改变原始指针的值。这在函数中经常用于修改指针的指向,例如在函数中分配内存并将其地址存储在指针中。
相关文章:
C-数据结构-平横二叉树
平衡二叉树(Balanced Binary Tree)是一种二叉树,其中任意节点的两棵子树的高度差不超过 1。也可以说是一棵空树或者左右子树高度差不超过 1 的二叉树。 特点和性质 高度平衡:平衡二叉树是一种高度平衡的二叉树,任意节…...
算法训练营day41
动态规划理论基础(主要就是确定动态规划的几个步骤) 题目1:509. 斐波那契数 - 力扣(LeetCode) class Solution { public:int fib(int n) {if(n 0) return 0;if(n 1) return 1;int dp1 0;int dp2 1;int dp3 0;fo…...
cesium开发实例分享
反正 cesium 看到的效果几乎都有...
字符串和字符串函数(1)
前言: 字符串在C语言中比较特别,没有单另的字符串类型,想要初始化字符串必须用字符变量的数组初始化,但是在C语言标准库函数中提供了大量能对字符串进行修改的函数,比如说可以实现字符串的的拷贝,字符串的追…...
基于springboot+vue的班级综合测评管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
蓝海项目揭秘:跨境选品师的崛起与挑战
随着全球化贸易的日益深入和电子商务的蓬勃发展,跨境选品师这一新兴职业逐渐走进人们的视野。跨境选品师,顾名思义,就是专门负责为跨境电商平台挑选和推荐适合海外市场的商品的专业人士。那么,跨境选品师这一职业能否被视为一个蓝…...
酷黑简洁大气体育直播自适应模板赛事直播门户网站源码
源码名称:酷黑简洁大气体育直播自适应模板赛事直播门户网站源码 开发环境:帝国cms 7.5 安装环境:phpmysql 支持PC与手机端同步生成html(多端同步生成插件) 带软件采集,可以挂着自动采集发布,无…...
2024年电工杯高校数学建模竞赛(B题) 建模解析| 大学生平衡膳食食谱的优化设计
问题重述及方法概述 问题1:膳食食谱的营养分析评价及调整 数学方法:线性规划模型、营养素评价模型、比较分析 可视化数据图:营养素含量表、营养素摄入量对比图、营养素缺乏情况图 问题2:基于附件3的日平衡膳食食谱的优化设计 数…...
学习编程对英语要求高吗?
学习编程并不一定需要高深的英语水平。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我在后台发给你。 虽然一些编程资源和文档可能…...
使用 Django 和 RabbitMQ 构建高效的消息队列系统
文章目录 RabbitMQ 简介Django 中使用 RabbitMQ总结与拓展 在现代的 Web 应用程序开发中,构建一个高效的消息队列系统变得越来越重要。使用消息队列可以帮助我们解耦系统中不同模块的任务,并提高系统的性能和可扩展性。本文将介绍如何结合 Django 和 Rab…...
Pycharm常见问题1
问题: ValueError at /user/users/ The view user.views.get_users didnt return an HttpResponse object. It returned None instead. 问题分析: 视图user.views.get_users未返回HttpResponse对象,它返回值为None。也就是说在视图文件没有…...
开发一个comfyui的自定义节点
文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…...
Prime算法构造最小生成树(加点法)
一、算法逻辑 想要轻松形象理解Prime的算法逻辑,视频肯定比图文好。 小编看过很多求相关的教学视频,这里选出一个我认为最好理解的这一款安利给大家。 因为他不仅讲解细致,而且还配合了动画演示,可以说把一个抽象的东西讲的非常…...
【VTKExamples::Utilities】第五期 CommandSubclass
很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例CommandSubclass,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. CommandSubclass …...
重生之 SpringBoot3 入门保姆级学习(04、 包扫描)
重生之 SpringBoot3 入门保姆级学习(04、 包扫描) 2.1 包扫描 2.1 包扫描 默认包扫描规则: SpringBootApplication 标注的就是主程序 SpringBoot 只会扫描主程序下面的包 自动的 component-scan 功能 在 SpringBootApplication 添加参数可以…...
VectorDBBench在windows的调试
VectorDBBench在windows的调试 VectorDBBench是一款向量数据库基准测试工具,支持milvus、Zilliz Cloud、Elastic Search、Qdrant Cloud、Weaviate Cloud 、 PgVector、PgVectorRS等,可以测试其QPS、时延、recall。 VectorDBBench是一款使用python编写的…...
KAN(Kolmogorov-Arnold Network)的理解 1
系列文章目录 第一部分 KAN的理解——数学背景 文章目录 系列文章目录前言KAN背后的数学原理:Kolmogorov-Arnold representation theorem 前言 这里记录我对于KAN的探索过程,每次会尝试理解解释一部分问题。欢迎大家和我一起讨论。 KAN tutorial KAN背…...
Vue 项目中使用 Element UI库(Element UI 是一套基于 Vue.js 的桌面端组件库)
1. 安装 Element UI npm install element-plusnext 2.引入 Element UI(在main.js中引入组件,注意要引入.css文件,图标也要单独引用) import { createApp } from vueimport ElementPlus from element-plusimport element-plus/dist/index.css…...
C++240527
定义自己的命名空间 my_sapce,在 my_sapce 中定义 string 类型的变量 s1,再 定义一个函数 完成 对字符串的逆置 。 #include <iostream>//导入 标准命名空间,cout 和 endl 标识符 存在于标准命名空间中 using namespace std;//定义了自…...
揭秘动态网页爬取:步骤与实战技巧
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言 二、动态网页爬取步骤 三、实战技巧分享 四、总结 一、引言 在大数据时代&#…...
5个React条件渲染技巧:从基础到实战的完整指南
5个React条件渲染技巧:从基础到实战的完整指南 【免费下载链接】react-fundamentals Material for my React Fundamentals Workshop 项目地址: https://gitcode.com/gh_mirrors/re/react-fundamentals React条件渲染是构建动态用户界面的核心技能,…...
OpenClaw对话日志分析:Qwen3.5-9B优化任务执行成功率
OpenClaw对话日志分析:Qwen3.5-9B优化任务执行成功率 1. 问题背景与数据准备 去年开始使用OpenClaw对接Qwen3.5-9B模型时,我发现一个有趣现象:同样的自动化任务,在不同时段执行成功率波动很大。有时能完美完成文件整理和邮件发送…...
GHelper工具:解决华硕笔记本性能控制难题的轻量化方案
GHelper工具:解决华硕笔记本性能控制难题的轻量化方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Sc…...
如何对比 SEO 优化公司的服务
了解 SEO 优化公司的服务 在当今数字化时代,SEO(搜索引擎优化)已经成为了企业在互联网上获得曝光和流量的重要手段。选择一家合适的SEO优化公司,对于提升网站排名和增加业务机会至关重要。如何对比SEO优化公司的服务呢࿱…...
终极硬件指纹伪装指南:如何用EASY-HWID-SPOOFER保护你的数字隐私
终极硬件指纹伪装指南:如何用EASY-HWID-SPOOFER保护你的数字隐私 【免费下载链接】EASY-HWID-SPOOFER 基于内核模式的硬件信息欺骗工具 项目地址: https://gitcode.com/gh_mirrors/ea/EASY-HWID-SPOOFER 在数字时代,你的电脑硬件指纹就像数字世界…...
MiniCPM-V-2_6政务场景应用:身份证/营业执照图像识别+结构化提取
MiniCPM-V-2_6政务场景应用:身份证/营业执照图像识别结构化提取 1. 引言:让政务文档处理更智能高效 在日常政务工作中,工作人员经常需要处理大量的身份证和营业执照图像。传统的人工录入方式不仅效率低下,还容易出错。一张身份证…...
如何高效参与GoPay开源支付项目开发:完整贡献指南
如何高效参与GoPay开源支付项目开发:完整贡献指南 【免费下载链接】gopay 微信、支付宝、通联支付、拉卡拉、PayPal、Apple 的Go版本SDK。【极简、易用的聚合支付SDK】 项目地址: https://gitcode.com/gh_mirrors/go/gopay GoPay是一款极简、易用的聚合支付S…...
intv_ai_mk11基础教程:打开即用的Llama文本生成器使用全流程详解
intv_ai_mk11基础教程:打开即用的Llama文本生成器使用全流程详解 1. 快速了解intv_ai_mk11 intv_ai_mk11是一个基于Llama架构的中等规模文本生成模型,特别适合日常办公和内容创作场景。想象一下,你有一个随时待命的文字助手,可以…...
OpenClaw安全实践:Qwen3.5-9B本地化部署防止敏感数据泄露
OpenClaw安全实践:Qwen3.5-9B本地化部署防止敏感数据泄露 1. 为什么需要本地化部署? 去年我在处理一份涉及商业机密的财务分析报告时,第一次意识到公有云API的潜在风险。当时使用某知名云服务商的文本分析接口,虽然服务条款承诺…...
微信小程序端集成实践:打造手机上的国风绘画工具
微信小程序端集成实践:打造手机上的国风绘画工具 想不想随时随地,掏出手机就能创作一幅充满诗意的国风画作?以前这可能需要多年的绘画功底,但现在,借助AI的力量,每个人都能成为自己手机里的国风画师。今天…...
