平衡二叉树c语言版

一、定义二叉树结点结构体
/**
 * 定义平衡二叉树结点
*/
struct avlbinarytree
{    
    //数据域
    NodeData*  data;
    ///树高
    int  h;
    struct avlbinarytree*  left;
    struct avlbinarytree*  right;
};
typedef struct avlbinarytree AVLNode;
二、声明函数的操作
/**
 * 创建结点
*/
AVLNode* create_avlbinarytree_node(NodeData* data);


/***
 * 计算树高度
*/
int   get_avltree_h(AVLNode* childRoot);

/**
 * 添加结点
*/
void  insert_avlbinarytree_node(AVLNode** tree,NodeData*  data);

/**
 * 平衡操作
*/
void  do_avltree_roate(AVLNode** root);

/**
 * 前序遍历
*/
void  per_order_avlbinarytree(AVLNode* root);


/**
 * LL型,左孩子的左子树添加删除引起的失衡
 *         5                                       3
 *       .   .           平衡操作                .     .
 *      3     6      -------------->            2     5 
 *     .  .                                    .    .    .
 *    2    4                                  1     4     6
 *   .
 *  1
 * 
 * 平衡操作:左子树整体右旋,将根节点左孩子提到根节点,原根结点变成新根节点的右孩子,新根结点的原右孩子变成原根节点的左孩子
 *
*/
void  ll_roate_avl(AVLNode** root);

/**
 * RR型右孩子的右子树添加删除引起的失衡
 *          2                               4
 *       .     .                         .     .
 *       1     4      ------->           2     6  
 *          .    .                     .   .  .    
 *          3    6                     1   3  5
 *             .  
 *             5
 *
*/

void  rr_roate_avl(AVLNode** root);
/**
 * LR型,左孩子的右子树添加删除引起的失衡
 *         5                    5                           3
 *       .   .               .     .                     .     .
 *      2     6              3     6                     2     5 
 *     .  .       ------> .   .          ------->      .     .    .
 *         .            .
 *          4          1
 *平衡操作:左子树先做一次RR左旋,再做一次LL右旋
*/
void  lr_roate_avl(AVLNode** root);


/**
 * RL型右孩子的左子树添加删除引起的失衡
 *          2                        2                                4
 *       .     .                   .    .                           .     .
 *       1     5    ------->      1     4       ---->               2       5
 *          .    .                    .    .                      .    .      .
 *          4    6                   3      5                    1      3      6
 *         .                                  .
 *        3                                     6
 *        
 *平衡操作: 先将右子树做一次LL右旋,在做一次RR左旋
*/
void  rl_roate_avl(AVLNode** root);
三、平衡二叉树操作函数定义

/**
 * 创建结点
 */
AVLNode *create_avlbinarytree_node(NodeData *data)
{
  AVLNode *node = malloc(sizeof(AVLNode *));
  if (node == NULL)
  {
    perror("创建AVLNode结点失败");
    return NULL;
  }
  node->data = malloc(sizeof(NodeData *));
  if (node->data == NULL)
  {
    perror("AVLNode数据域分配内存空间失败");
    return NULL;
  }
  *(node->data) = *data;
  node->h = 1;
  node->left = NULL;
  node->right = NULL;
  return node;
}
/**
 * 获取树高
 */
int get_avltree_h(AVLNode *childRoot)
{
  if (childRoot == NULL)
  {
    return 0;
  }
  int l = get_avltree_h(childRoot->left) + 1;
  int r = get_avltree_h(childRoot->right) + 1;
  return l > r ? l : r;
}

void insert_avlbinarytree_node(AVLNode **tree, NodeData *data)
{
  if (*tree == NULL)
  {
    AVLNode *newNode = create_avlbinarytree_node(data);
    *tree = newNode;
    return;
  }
  /// 左子树
  if (*data < *((*tree)->data))
  {

    insert_avlbinarytree_node(&((*tree)->left), data);
  }
  //右子树
  if (*data > *((*tree)->data))
  {
    insert_avlbinarytree_node(&((*tree)->right), data);
  }
}

void  do_avltree_roate(AVLNode** root)
{
    int lh = get_avltree_h((*root)->left);
    int rh = get_avltree_h((*root)->right);
    /// 左子树高于右子树造成的不平衡
    if(lh-rh>1)
    {
         int llh =  get_avltree_h((*root)->left->left);
         int lrh =  get_avltree_h((*root)->left->right);
         bool isLL = llh > lrh ;
         if(isLL)
           ll_roate_avl(root);
         else
           lr_roate_avl(root);
    }
    /// 右子树高于左子树造成的不平衡
    if(rh-lh>1)
    {
         int rlh =  get_avltree_h((*root)->right->left);
         int rrh =  get_avltree_h((*root)->right->right);
         bool isRR = rrh > rlh ;
         if(isRR)
           rr_roate_avl(root);
         else
           rl_roate_avl(root);      
    }
}

void per_order_avlbinarytree(AVLNode *root)
{
  if (root == NULL)
  {
    return;
  }
  printf("d-avlbinarytree:  %d\n", *(root->data));
  per_order_avlbinarytree(root->left);
  per_order_avlbinarytree(root->right);
}

void ll_roate_avl(AVLNode **root)
{
  printf("lr_roate_avl----LL型\n");
  //  (*root)->left = temp->right;
  //  temp->right = (*root);
  //  *root = temp; 
  
   AVLNode *temp =(*root)->left->right;
   (*root)->left->right = *root;
   *root =(*root)->left;
   (*root)->right->left= temp;
}

void rr_roate_avl(AVLNode **root)
{
  printf("lr_roate_avl----RR型\n");
  AVLNode *temp = (*root)->right->left;
  (*root)->right->left = *root;
  *root = (*root)->right;
  (*root)->left->right = temp;
}

void lr_roate_avl(AVLNode **root)
{
  printf("lr_roate_avl----LR型\n");
  AVLNode *leftTree = (*root)->left;
  rr_roate_avl(&leftTree);
  (*root)->left = leftTree;
  ll_roate_avl(root);
}

void rl_roate_avl(AVLNode **root)
{
  printf("lr_roate_avl----RL型\n");
  AVLNode *rightRoot = (*root)->right;
  ll_roate_avl(&rightRoot);
  (*root)->right = rightRoot;
  rr_roate_avl(root);
}
四、平衡二叉树测试
void   test_avlbinarytree()
{
 //RR型  {1,2,3,4,5,6};
 //LL型  {7,6,5,4,3,2,1};
 //LR型  {5,2,6,1,3,4};
 //RL型  {4,3,8,6,5,10};
 NodeData  arr[] = {4,3,8,6,5,10};
 int len = sizeof(arr)/sizeof(arr[0]);
 int i;
 AVLNode* root = NULL;
 for(i=0;i<len;i++)
 {
   insert_avlbinarytree_node(&root,&arr[i]);
   do_avltree_roate(&root);
 }
 printf("start 中序遍历---\n");
 per_order_avlbinarytree(root);

 int lh = get_avltree_h(root->left);
 int rh = get_avltree_h(root->right);
 printf("树高度lh= %d, rh= %d\n",lh,rh);
 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/137308.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu从源码编译gdal

删除旧版本 sudo apt remove libgdal* sudo apt remove gdal* sudo apt autoremove下载geos、proj和gdal https://github.com/libgeos/geos/releases 这里使用的是3.12.1版本&#xff1a; https://github.com/OSGeo/PROJ/releases 这里使用的是9.3.0版本&#xff1a; ht…

网络渗透测试(TCP/IP)理论篇

TCP/IP体系 垂直服务&#xff1a;底层为高层服务 TCP/IP体系结构是一个分层的协议体系&#xff0c;由多个层次组成&#xff0c;每个层次都负责不同的功能。以下是TCP/IP体系结构的主要层次&#xff1a; 物理层&#xff08;Physical Layer&#xff09;&#xff1a;该层负责传输…

Ubuntu20.04 安装微信 【wine方式安装】推荐

安装步骤: 第一步:安装 WineHQ 安装包 先安装wine,根据官网指导安装即可。下载 - WineHQ Wikihttps://wiki.winehq.org/Download_zhcn 如果您之前安装过来自其他仓库的 Wine 安装包,请在尝试安装 WineHQ 安装包之前删除它及依赖它的所有安装包(如:wine-mono、wine-gec…

JAVA小游戏 “拼图”

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import jav…

开源集群管理系统对比分析:Kubernetes 与 Apache Mesos

集群管理系统是关键的软件解决方案&#xff0c;可以在互连机器网络中有效分配和利用计算资源。毫无疑问&#xff0c;它们通过确保可扩展性、高可用性和有效的资源管理在现代计算中发挥着至关重要的作用&#xff0c;这使得它们对于运行复杂的应用程序、管理数据中心以及进一步增…

Run Legends将健身运动游戏化,使用户保持健康并了解Web3游戏

最近&#xff0c;我们有机会采访Talofa Games的首席执行官兼创始人Jenny Xu&#xff0c;一起讨论游戏开发&#xff0c;Talofa Games是Run Legends这款健身游戏的开发工作室。她已经创作了超过一百款游戏&#xff0c;对于推动游戏的可能性并将她的创造力和叙事技巧带入她最喜爱的…

【Java系列】SpringBoot 集成MongoDB 详细介绍

目录 写在前面 一、步骤介绍 步骤 1: 添加 MongoDB 依赖 步骤 2: 配置 MongoDB 连接信息 步骤 3: 创建实体类 步骤 4: 创建 Repository 接口 步骤 5: 使用 Repository 进行操作 二、特殊处理 写在前面 在Spring Boot中集成MongoDB的过程相对简单&#xff0c;以下是一个…

参与活动如何进行地区的限制

对活动地区限制分为两步&#xff1a;一是管理端配置&#xff0c;而是移动端限制 移动端限制 使用高德获取经纬度&#xff08;需要引入高德库&#xff1a;https://webapi.amap.com/maps&#xff09;&#xff0c;如果是app也可以调用jsapi获取经纬度 export const checkAppPermis…

php字符串处理函数的使用

php字符串处理函数的使用 trim() trim()函数的功能用于去除字符串首尾的空白字符(包括空格、制表符、换行符等&#xff09;。它可以用于清理用户输入的数据或去除字符串中的多余空格。 <?php $char" holle world! ";echo trim($char) ?>str_repl…

CMake 判断操作系统类型

上回的CMakeLists.txt里面有一句,if (WIN32)......endif(WIN32); 根据资料,这是判断操作系统是否是Windows; 下面单独看一下; 一个CMakeLists.txt文件如下; if(WIN32)# 如果是 Windowsmessage("当前操作系统为 Windows") elseif(UNIX AND NOT APPLE)# 如果…

git基本操作(配图超详细讲解)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 创建git本地仓库 配置仓库 认识工作区&#xff0c;暂存区&#xff0c;版本库 修改文件 版本回退 撤销修改 删除文件 创建git本地仓库 要提前说的是&#xff0c;仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂…

重磅解读 | 阿里云 云网络领域关键技术创新

云布道师 10 月 31 日&#xff0c;杭州云栖大会&#xff0c;阿里云技术主论坛带来了一场关于阿里云主力产品与技术创新的深度解读&#xff0c;阿里云网络产品线负责人祝顺民带来《云智创新&#xff0c;网络随行》的主题发言&#xff0c;针对阿里云飞天洛神云网络&#xff08;下…

入行IC | 从小白助理级,到总监专家级,到底要经历怎样的成长阶段呢?

《中国集成电路产业人才发展报告》是业内和IC设计、IC人才都息息相关的一份报告。 &#xff08;文末可领全部报告资料&#xff09; * 从报告数据来看&#xff0c;无论在半导体产业的哪个环节&#xff0c;个人发展路径和年薪待遇都是逐级攀升的趋势。 那么从小白助理级&a…

卷积神经网络(VGG-19)灵笼人物识别

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3. 查看数据 二、数据预处理1. 加载数据2. 可视化数据3. 再次检查数据4. 配置数据集5. 归一化 三、构建VGG-19网络1. 官方模型&#xff08;已打包好&#xff…

docker通过挂载conf文件启动redis

初衷&#xff1a;之前直接在启动脚本中没有挂载配置文件&#xff0c;并且直接设置了密码等&#xff0c;后续要使用集群&#xff0c;苦于无法修改配置&#xff0c;进入redis容器也找不到redis.conf&#xff0c;所以写这个文章用来使用redis的配置&#xff0c;来达到后续都可动态…

掌握深度学习利器——TensorFlow 2.x实战应用与进阶

掌握深度学习利器——TensorFlow 2.x实战应用与进阶 摘要&#xff1a;随着人工智能技术的飞速发展&#xff0c;深度学习已成为当下最热门的领域之一。作为深度学习领域的重要工具&#xff0c;TensorFlow 2.x 备受关注。本文将通过介绍TensorFlow 2.x的基本概念和特性&#xff…

Java语言的特点||运算符

Java语言的特点||运算符 1&#xff1a;2&#xff1a;JDK, JRE&#xff0c;JVM知识&#xff1a;3&#xff1a;注释4&#xff1a;标识符5&#xff1a; Java编译过程&#xff1a;6&#xff1a;赋值7&#xff1a;switch8:布尔表达式9&#xff1a;判定素数10&#xff1a;打印 1 - 10…

stack和queue简单实现(容器适配器)

容器适配器 stack介绍stack模拟实现queue 介绍queue模拟实现deque stack介绍 stack模拟实现 以前我们实现stack&#xff0c;需要像list,vector一样手动创建成员函数&#xff0c;成员变量。但是stack作为容器适配器&#xff0c;我们有更简单的方法来实现它。 可以利用模板的强大…

代码随想录二刷 | 链表 | 翻转链表

代码随想录二刷 &#xff5c; 链表 &#xff5c; 翻转链表 题目描述解题思路 & 代码实现双指针法递归法 206.翻转链表 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4…

kolla 安装多节点openstack kolla部署openstack

Kolla 概述&#xff1a; Kolla是OpenStack下用于自动化部署的一个项目&#xff0c;它基于docker和ansible来实现&#xff0c;其中docker主要负责镜像制作和容器管理&#xff0c;ansible主要负责环境的部署和管理。Kolla实际上分为两部分&#xff1a;Kolla部分提供了生产环境级…
最新文章