当前位置:   article > 正文

平衡二叉树及优化(细节图解)(时间复杂度O(N))_平衡树 复杂度

平衡树 复杂度

一.平衡二叉树

定义:平衡二叉树是一种高度平衡的二叉树,它的节点结构和操作方式有特殊的规律。平衡二叉树的定义是:任意节点的子树的高度差都小于等于1。 平衡二叉树的作用是提高查询的效率,保证查询的时间复杂度为O(logn)。

平衡二叉树会使用到[递归(这里有递归基础)]

1.1平衡二叉树定义

二.构建二叉树节点

2.1构建结构体

  1. typedef char BTDataType;
  2. typedef struct BinaryTreeNode {
  3. BTDataType data;
  4. struct BinaryTreeNode* left;
  5. struct BinaryTreeNode* right;
  6. }BTNode;

2.2连接图例

 2.3创建节点

  1. BTNode* CreateNode(BTDataType x)//创建节点
  2. {
  3. BTNode* node = (BTNode*)malloc(sizeof(BTNode));
  4. node->data = x;
  5. node->left = NULL;
  6. node->right = NULL;
  7. return node;
  8. }

三.构建二叉树

3.1快速构建二叉树

  1. BTNode* A = CreateNode(1);
  2. BTNode* B = CreateNode(2);
  3. BTNode* C = CreateNode(3);
  4. BTNode* D = CreateNode(4);
  5. BTNode* E = CreateNode(5);
  6. BTNode* A2 = CreateNode(1);
  7. BTNode* B2 = CreateNode(2);
  8. BTNode* C2 = CreateNode(3);
  9. BTNode* D2 = CreateNode(4);
  10. BTNode* E2 = CreateNode(5);
  11. BTNode* F2 = CreateNode(5);
  12. //快速构建树A
  13. A->left = B;
  14. A->right = C;
  15. B->left = D;
  16. B->right = E;
  17. //快速构建树A2
  18. A2->left = B2;
  19. A2->right = C2;
  20. B2->left = D2;
  21. C2->right = E2;
  22. E2->right = F2;

 3.2构建的两颗树

 四.平衡二叉树(O(n^2))

4.1平衡二叉树代码

方法一(未优化):平衡二叉树的判断思路主要是看该二叉树是否满足两个条件:首先,它需要是一颗[二叉排序树];其次,它的任何一个节点的左子树或者右子树都需要是平衡二叉树,也就是说左右子树的高度差必须小于等于1。

具体实现上,我们可以使用递归的方法来进行判断。首先检查当前子树是否是平衡二叉树,然后递归地对左子树和右子树做同样的检查。在检查过程中,需要求出每个节点的左右子树的高度,并判断它们的高度差是否超过了1。只有当每个节点都满足上述条件时,这颗二叉树才可以被称为是平衡二叉树。

  1. int TreeDepth(BTNode* root)//树的高度
  2. {
  3. if (root == NULL)
  4. return 0;
  5. int leftDepth = TreeDepth(root->left);
  6. int rightDepth = TreeDepth(root->right);
  7. return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  8. }
  9. //平衡二叉树(前序)
  10. //TreeDepth()计算当前树的高度
  11. bool isBalanced(BTNode* root)
  12. {
  13. if (root == NULL)
  14. return true;
  15. int gap = TreeDepth(root->left) - TreeDepth(root->right);
  16. if (abs(gap) > 1)
  17. return false;
  18. return isBalanced(root->left) && isBalanced(root->right);
  19. }

4.2计算树的高度图解

4.3平衡二叉树图解

对比当前根(root)左右子树的高度,这里每次对比的时候都要调用TreeDepth()计算当前根左右子树的高度,又因为TreeDepth()的时间复杂度为O(n),

所以整个isBalanced()的最坏时间复杂度为O(n^2)

五.平衡二叉树优化(O(n))

5.1平衡二叉树代码优化

从左子树叶子节点开始。判断的同时,把高度带给上一次调用的父亲节点,这里不需要再递归求树的高度,优化之后就不像之前存在大量的重复计算。isBalanced1()优化后的平衡二叉树代码,时间复杂度为O(N).

可以通过【前序中序后续递归】尝试打印出树中的数据。

  1. bool _isBalanced1(BTNode* root, int* pDepth)
  2. {
  3. if (root == NULL)
  4. {
  5. *pDepth = 0;
  6. return true;
  7. }
  8. else
  9. {
  10. int leftDepth = 0;
  11. if (_isBalanced1(root->left, &leftDepth) == 0)
  12. {
  13. return false;
  14. }
  15. int rightDepth = 0;
  16. if (_isBalanced1(root->right, &rightDepth) == 0)
  17. {
  18. return false;
  19. }
  20. if (abs(leftDepth - rightDepth) > 1)
  21. return false;
  22. *pDepth = leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  23. return true;
  24. }
  25. }
  26. bool isBalanced1(BTNode* root)
  27. {
  28. int Depth = 0;
  29. return _isBalanced1(root, &Depth);
  30. }

5.1 平衡二叉树图解

六.全部代码

6.1全部代码

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<assert.h>
  4. #include<stdbool.h>
  5. typedef char BTDataType;
  6. typedef struct BinaryTreeNode {
  7. BTDataType data;
  8. struct BinaryTreeNode* left;
  9. struct BinaryTreeNode* right;
  10. }BTNode;
  11. BTNode* CreateNode(BTDataType x)//创建节点
  12. {
  13. BTNode* node = (BTNode*)malloc(sizeof(BTNode));
  14. node->data = x;
  15. node->left = NULL;
  16. node->right = NULL;
  17. return node;
  18. }
  19. int TreeDepth(BTNode* root)//树的高度
  20. {
  21. if (root == NULL)
  22. return 0;
  23. int leftDepth = TreeDepth(root->left);
  24. int rightDepth = TreeDepth(root->right);
  25. return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  26. }
  27. //平衡二叉树(前序)
  28. //TreeDepth()计算当前树的高度
  29. bool isBalanced(BTNode* root)
  30. {
  31. if (root == NULL)
  32. return true;
  33. int gap = TreeDepth(root->left) - TreeDepth(root->right);
  34. if (abs(gap) > 1)
  35. return false;
  36. return isBalanced(root->left) && isBalanced(root->right);
  37. }
  38. bool _isBalanced1(BTNode* root, int* pDepth)
  39. {
  40. if (root == NULL)
  41. {
  42. *pDepth = 0;
  43. return true;
  44. }
  45. else
  46. {
  47. int leftDepth = 0;
  48. if (_isBalanced1(root->left, &leftDepth) == 0)
  49. {
  50. return false;
  51. }
  52. int rightDepth = 0;
  53. if (_isBalanced1(root->right, &rightDepth) == 0)
  54. {
  55. return false;
  56. }
  57. if (abs(leftDepth - rightDepth) > 1)
  58. return false;
  59. *pDepth = leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  60. return true;
  61. }
  62. }
  63. bool isBalanced1(BTNode* root)
  64. {
  65. int Depth = 0;
  66. return _isBalanced1(root, &Depth);
  67. }
  68. int main()
  69. {
  70. BTNode* A = CreateNode(1);
  71. BTNode* B = CreateNode(2);
  72. BTNode* C = CreateNode(3);
  73. BTNode* D = CreateNode(4);
  74. BTNode* E = CreateNode(5);
  75. BTNode* A2 = CreateNode(1);
  76. BTNode* B2 = CreateNode(2);
  77. BTNode* C2 = CreateNode(3);
  78. BTNode* D2 = CreateNode(4);
  79. BTNode* E2 = CreateNode(5);
  80. BTNode* F2 = CreateNode(5);
  81. //快速构建树A
  82. A->left = B;
  83. A->right = C;
  84. B->left = D;
  85. B->right = E;
  86. //快速构建树A2
  87. A2->left = B2;
  88. A2->right = C2;
  89. B2->left = D2;
  90. C2->right = E2;
  91. E2->right = F2;
  92. printf("A这棵树为平衡二叉树吗? 1是 0不是\n");
  93. bool a = isBalanced1(A);
  94. printf("A=%d", a);
  95. printf("\n");
  96. printf("A2这棵树为平衡二叉树吗? 1是 0不是\n");
  97. bool b = isBalanced1(A2);
  98. printf("A2=%d", b);
  99. printf("\n");
  100. return 0;
  101. }

 6.2运行结果

   以上就是本期内容,欢迎参考指正,如有不懂,欢迎评论或私信出下期!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/681195
推荐阅读
相关标签
  

闽ICP备14008679号