平衡二叉树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);
 
}
相关推荐
DdddJMs__1359 分钟前
C语言 | Leetcode C语言题解之第458题可怜的小猪
c语言·leetcode·题解
哎呀呀嗯呀呀15 分钟前
class 031 位运算的骚操作
java·算法·位运算
时清云31 分钟前
【算法】合并两个有序链表
前端·算法·面试
凯子坚持 c1 小时前
C语言复习概要(四)
c语言·开发语言
轩辰~1 小时前
磁盘存储链式结构——B树与B+树
数据结构·b树·算法
2401_857297911 小时前
秋招内推2025-招联金融
java·前端·算法·金融·求职招聘
通信仿真实验室1 小时前
MATLAB使用眼图分析QPSK通信系统接收端匹配滤波后的信号
开发语言·算法·matlab
通信仿真实验室2 小时前
(15)衰落信道模型作用于信号是相乘还是卷积
开发语言·人工智能·算法·matlab
Run with the Wind2 小时前
【2024.9.29练习】R 格式
算法
Jeremy_121382 小时前
三种波束形成方法的区别(MVDR、MMSE以及MSNR波束形成器)
算法