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′|┛ 嗷~~ 目录 一、引言 二、动态网页爬取步骤 三、实战技巧分享 四、总结 一、引言 在大数据时代&#…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 是Linux系统下用于监视系统输入输出设备和CPU使…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
