• 平衡二叉树c语言版


    一、定义二叉树结点结构体
    1. /**
    2. * 定义平衡二叉树结点
    3. */
    4. struct avlbinarytree
    5. {
    6. //数据域
    7. NodeData* data;
    8. ///树高
    9. int h;
    10. struct avlbinarytree* left;
    11. struct avlbinarytree* right;
    12. };
    13. typedef struct avlbinarytree AVLNode;
    二、声明函数的操作
    1. /**
    2. * 创建结点
    3. */
    4. AVLNode* create_avlbinarytree_node(NodeData* data);
    5. /***
    6. * 计算树高度
    7. */
    8. int get_avltree_h(AVLNode* childRoot);
    9. /**
    10. * 添加结点
    11. */
    12. void insert_avlbinarytree_node(AVLNode** tree,NodeData* data);
    13. /**
    14. * 平衡操作
    15. */
    16. void do_avltree_roate(AVLNode** root);
    17. /**
    18. * 前序遍历
    19. */
    20. void per_order_avlbinarytree(AVLNode* root);
    21. /**
    22. * LL型,左孩子的左子树添加删除引起的失衡
    23. * 5 3
    24. * . . 平衡操作 . .
    25. * 3 6 --------------> 2 5
    26. * . . . . .
    27. * 2 4 1 4 6
    28. * .
    29. * 1
    30. *
    31. * 平衡操作:左子树整体右旋,将根节点左孩子提到根节点,原根结点变成新根节点的右孩子,新根结点的原右孩子变成原根节点的左孩子
    32. *
    33. */
    34. void ll_roate_avl(AVLNode** root);
    35. /**
    36. * RR型右孩子的右子树添加删除引起的失衡
    37. * 2 4
    38. * . . . .
    39. * 1 4 -------> 2 6
    40. * . . . . .
    41. * 3 6 1 3 5
    42. * .
    43. * 5
    44. *
    45. */
    46. void rr_roate_avl(AVLNode** root);
    47. /**
    48. * LR型,左孩子的右子树添加删除引起的失衡
    49. * 5 5 3
    50. * . . . . . .
    51. * 2 6 3 6 2 5
    52. * . . ------> . . -------> . . .
    53. * . .
    54. * 4 1
    55. *平衡操作:左子树先做一次RR左旋,再做一次LL右旋
    56. */
    57. void lr_roate_avl(AVLNode** root);
    58. /**
    59. * RL型右孩子的左子树添加删除引起的失衡
    60. * 2 2 4
    61. * . . . . . .
    62. * 1 5 -------> 1 4 ----> 2 5
    63. * . . . . . . .
    64. * 4 6 3 5 1 3 6
    65. * . .
    66. * 3 6
    67. *
    68. *平衡操作: 先将右子树做一次LL右旋,在做一次RR左旋
    69. */
    70. void rl_roate_avl(AVLNode** root);
    三、平衡二叉树操作函数定义
    1. /**
    2. * 创建结点
    3. */
    4. AVLNode *create_avlbinarytree_node(NodeData *data)
    5. {
    6. AVLNode *node = malloc(sizeof(AVLNode *));
    7. if (node == NULL)
    8. {
    9. perror("创建AVLNode结点失败");
    10. return NULL;
    11. }
    12. node->data = malloc(sizeof(NodeData *));
    13. if (node->data == NULL)
    14. {
    15. perror("AVLNode数据域分配内存空间失败");
    16. return NULL;
    17. }
    18. *(node->data) = *data;
    19. node->h = 1;
    20. node->left = NULL;
    21. node->right = NULL;
    22. return node;
    23. }
    24. /**
    25. * 获取树高
    26. */
    27. int get_avltree_h(AVLNode *childRoot)
    28. {
    29. if (childRoot == NULL)
    30. {
    31. return 0;
    32. }
    33. int l = get_avltree_h(childRoot->left) + 1;
    34. int r = get_avltree_h(childRoot->right) + 1;
    35. return l > r ? l : r;
    36. }
    37. void insert_avlbinarytree_node(AVLNode **tree, NodeData *data)
    38. {
    39. if (*tree == NULL)
    40. {
    41. AVLNode *newNode = create_avlbinarytree_node(data);
    42. *tree = newNode;
    43. return;
    44. }
    45. /// 左子树
    46. if (*data < *((*tree)->data))
    47. {
    48. insert_avlbinarytree_node(&((*tree)->left), data);
    49. }
    50. //右子树
    51. if (*data > *((*tree)->data))
    52. {
    53. insert_avlbinarytree_node(&((*tree)->right), data);
    54. }
    55. }
    56. void do_avltree_roate(AVLNode** root)
    57. {
    58. int lh = get_avltree_h((*root)->left);
    59. int rh = get_avltree_h((*root)->right);
    60. /// 左子树高于右子树造成的不平衡
    61. if(lh-rh>1)
    62. {
    63. int llh = get_avltree_h((*root)->left->left);
    64. int lrh = get_avltree_h((*root)->left->right);
    65. bool isLL = llh > lrh ;
    66. if(isLL)
    67. ll_roate_avl(root);
    68. else
    69. lr_roate_avl(root);
    70. }
    71. /// 右子树高于左子树造成的不平衡
    72. if(rh-lh>1)
    73. {
    74. int rlh = get_avltree_h((*root)->right->left);
    75. int rrh = get_avltree_h((*root)->right->right);
    76. bool isRR = rrh > rlh ;
    77. if(isRR)
    78. rr_roate_avl(root);
    79. else
    80. rl_roate_avl(root);
    81. }
    82. }
    83. void per_order_avlbinarytree(AVLNode *root)
    84. {
    85. if (root == NULL)
    86. {
    87. return;
    88. }
    89. printf("d-avlbinarytree: %d\n", *(root->data));
    90. per_order_avlbinarytree(root->left);
    91. per_order_avlbinarytree(root->right);
    92. }
    93. void ll_roate_avl(AVLNode **root)
    94. {
    95. printf("lr_roate_avl----LL型\n");
    96. // (*root)->left = temp->right;
    97. // temp->right = (*root);
    98. // *root = temp;
    99. AVLNode *temp =(*root)->left->right;
    100. (*root)->left->right = *root;
    101. *root =(*root)->left;
    102. (*root)->right->left= temp;
    103. }
    104. void rr_roate_avl(AVLNode **root)
    105. {
    106. printf("lr_roate_avl----RR型\n");
    107. AVLNode *temp = (*root)->right->left;
    108. (*root)->right->left = *root;
    109. *root = (*root)->right;
    110. (*root)->left->right = temp;
    111. }
    112. void lr_roate_avl(AVLNode **root)
    113. {
    114. printf("lr_roate_avl----LR型\n");
    115. AVLNode *leftTree = (*root)->left;
    116. rr_roate_avl(&leftTree);
    117. (*root)->left = leftTree;
    118. ll_roate_avl(root);
    119. }
    120. void rl_roate_avl(AVLNode **root)
    121. {
    122. printf("lr_roate_avl----RL型\n");
    123. AVLNode *rightRoot = (*root)->right;
    124. ll_roate_avl(&rightRoot);
    125. (*root)->right = rightRoot;
    126. rr_roate_avl(root);
    127. }
    四、平衡二叉树测试
    1. void test_avlbinarytree()
    2. {
    3. //RR型 {1,2,3,4,5,6};
    4. //LL型 {7,6,5,4,3,2,1};
    5. //LR型 {5,2,6,1,3,4};
    6. //RL型 {4,3,8,6,5,10};
    7. NodeData arr[] = {4,3,8,6,5,10};
    8. int len = sizeof(arr)/sizeof(arr[0]);
    9. int i;
    10. AVLNode* root = NULL;
    11. for(i=0;i<len;i++)
    12. {
    13. insert_avlbinarytree_node(&root,&arr[i]);
    14. do_avltree_roate(&root);
    15. }
    16. printf("start 中序遍历---\n");
    17. per_order_avlbinarytree(root);
    18. int lh = get_avltree_h(root->left);
    19. int rh = get_avltree_h(root->right);
    20. printf("树高度lh= %d, rh= %d\n",lh,rh);
    21. }

  • 相关阅读:
    XSAN数据恢复-存储空间架构迁移时误格式化存储系统的XSAN数据恢复案例
    法学行政法论文选题有哪些?
    java计算机毕业设计springboot+vue员工管理系统
    在 SQL Server 中,可以使用内置函数 NEWID() 来生成一个随机的 GUID(全局唯一标识符)。可以将此 GUID 作为字符串拼接到查询结果中。
    Android Jni添加打印(C++打印)
    Python操作Excel教程(图文教程,超详细)Python xlwings模块详解,
    RHCE之搭建NFS服务器练习题
    Set接口和常用方法
    springboot学生成绩课堂表现过程性评价系统java
    PHP8中获取并删除数组中最后一个元素-PHP8知识详解
  • 原文地址:https://blog.csdn.net/fengchengwu2012/article/details/134504088