• Root of AVL Tree (25)


    1、题意

    求所有数插入后,根节点是哪个数

    2、两种代码:

    2.1 代码1:

    1. #include
    2. #include
    3. using namespace std;
    4. const int N = 30;
    5. int l[N],r[N],v[N],h[N],idx;
    6. void update(int u)// 计算子树的高度
    7. {
    8. h[u] = max(h[l[u]],h[r[u]]) + 1;
    9. }
    10. void R(int &u)// 右旋
    11. {
    12. int p = l[u];
    13. l[u] = r[p],r[p] = u;
    14. update(u),update(p);
    15. u = p;
    16. }
    17. void L(int &u)
    18. {
    19. int p = r[u];
    20. r[u] = l[p],l[p] = u;
    21. update(u),update(p);
    22. u = p;
    23. }
    24. int get_balance(int u)
    25. {
    26. //左子树高度减去右子树高度
    27. return h[l[u]] - h[r[u]];
    28. }
    29. void insert(int &u,int w)
    30. {
    31. if(!u) u = ++idx,v[u] = w; // 一开始u = 0
    32. else if(w
    33. {
    34. insert(l[u],w);
    35. if(get_balance(u)==2)
    36. {
    37. if(get_balance(l[u])==1) R(u);
    38. else L(l[u]),R(u);
    39. }
    40. }
    41. else
    42. {
    43. insert(r[u],w);
    44. if(get_balance(u)==2)
    45. {
    46. if(get_balance(r[u])==-1) L(u);
    47. else R(r[u]),L(u);
    48. }
    49. }
    50. update(u);// 每次都要统计一下高度,这个高度在不断的迭代
    51. }
    52. int main()
    53. {
    54. int n,root = 0;
    55. scanf("%d",&n);
    56. while(n--)
    57. {
    58. int w;
    59. scanf("%d",&w);
    60. insert(root,w);
    61. }
    62. cout<
    63. return 0;
    64. }

    2.2 手写AVL树

    1. // 一次机会手写AVL树
    2. #include
    3. #define LH 1
    4. #define EH 0
    5. #define RH -1
    6. using namespace std;
    7. struct AVLTreeNode
    8. {
    9. int value; // 值,平衡因子
    10. int BF;
    11. AVLTreeNode* lchild;// 左孩子
    12. AVLTreeNode* rchild;// 右孩子
    13. };
    14. // 平衡操作
    15. void RightRotation(AVLTreeNode* &pRoot);// 右旋操作
    16. void LeftRotation(AVLTreeNode* &pRoot);// 左旋操作
    17. void LeftBalance(AVLTreeNode* &pRoot);// 左平衡
    18. void RightBalance(AVLTreeNode* &pRoot);// 右平衡
    19. // 常规操作
    20. bool InsertAVL(AVLTreeNode* &pRoot,int value,bool &taller);
    21. int main()
    22. {
    23. std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    24. AVLTreeNode* pRoot = NULL;
    25. bool taller = false;
    26. int value,N;
    27. cin>>N;
    28. for(int i = 0;i
    29. {
    30. cin>>value;
    31. InsertAVL(pRoot,value,taller);
    32. }
    33. cout<value<
    34. return 0;
    35. }
    36. // 新节点插入成功,则返回true
    37. // taller 反映树是否长高
    38. bool InsertAVL(AVLTreeNode* &pRoot,int value,bool &taller)
    39. {
    40. if(!pRoot)
    41. {
    42. pRoot = new AVLTreeNode();
    43. pRoot->BF = EH;
    44. pRoot->value = value;
    45. pRoot->lchild = pRoot->rchild = NULL;
    46. taller = true;
    47. }
    48. else
    49. {
    50. if(value == pRoot->value)
    51. {
    52. taller = false;
    53. return false;
    54. }
    55. if(value < pRoot->value)
    56. {
    57. if(!InsertAVL(pRoot->lchild,value,taller))
    58. return false;
    59. if(taller)
    60. {
    61. switch(pRoot->BF)
    62. {
    63. case LH: // 原来左边偏高,还是插在了左边
    64. LeftBalance(pRoot);
    65. taller = false;// 处理后高度不变;
    66. break;
    67. case EH:// 原本等高,插左边后长高
    68. pRoot->BF = LH;
    69. taller = true;
    70. break;
    71. case RH:// 原本右侧高,插在左侧,高度不变
    72. pRoot->BF = EH;
    73. taller = false;
    74. break;
    75. }
    76. }
    77. }
    78. else
    79. {
    80. if(!InsertAVL(pRoot->rchild,value,taller))
    81. return false;
    82. if(taller)
    83. {
    84. switch(pRoot->BF)
    85. {
    86. case LH:// 原本左侧高,插在了右侧,登高
    87. pRoot->BF = EH;
    88. taller = false;
    89. break;
    90. case EH:
    91. pRoot->BF = RH;
    92. taller = true;
    93. break;
    94. case RH:;
    95. RightBalance(pRoot);
    96. taller = false;
    97. break;
    98. }
    99. }
    100. }
    101. }
    102. return true;
    103. }
    104. // 左旋,以pRoot为根节点的树进行左旋处理,并调整好父子连接
    105. void LeftRotation(AVLTreeNode* &pRoot)
    106. {
    107. // pRoot现在为失衡节点,pRitht为pRoot的右子节点,pRoot,pRitht进行左旋处理
    108. AVLTreeNode* pRight = pRoot->rchild;
    109. pRoot->rchild = pRight->lchild;
    110. pRight->lchild = pRoot;
    111. pRoot = pRight;
    112. }
    113. // 右旋,以pRoot为根节点的树进行右旋处理,并调整好父子连接
    114. void RightRotation(AVLTreeNode* &pRoot)
    115. {
    116. // pRoot现在为失衡节点,pleft为pRoot的左子节点,对pRoot和pLeft进行右旋
    117. AVLTreeNode *pLeft = pRoot->lchild;
    118. pRoot->lchild = pLeft->rchild;
    119. pLeft->rchild = pRoot;
    120. pRoot = pLeft;
    121. }
    122. // 对左边的失衡部分进行平衡处理
    123. void LeftBalance(AVLTreeNode* &pRoot)
    124. {
    125. AVLTreeNode *pLeft,*pLeftRight;
    126. pLeft = pRoot->lchild;
    127. switch(pLeft->BF)
    128. {
    129. case LH: // LL型
    130. pRoot->BF = EH;
    131. pLeft->BF = EH;
    132. RightRotation(pRoot);
    133. break;
    134. case RH: // LR型
    135. pLeftRight = pLeft->rchild;
    136. switch(pLeftRight->BF)
    137. {
    138. case LH:
    139. pRoot->BF = RH;
    140. pLeft->BF = EH;
    141. break;
    142. case EH:
    143. pRoot->BF = EH;
    144. pLeft->BF = EH;
    145. break;
    146. case RH:
    147. pRoot->BF = EH;
    148. pLeft->BF = LH;
    149. break;
    150. }
    151. pLeftRight->BF = EH;
    152. LeftRotation(pRoot->lchild);
    153. RightRotation(pRoot);// 这里不能写出pleft
    154. break;
    155. }
    156. }
    157. void RightBalance(AVLTreeNode* &pRoot)
    158. {
    159. AVLTreeNode* pRight,*pRightLeft;
    160. pRight = pRoot->rchild;
    161. switch(pRight->BF)
    162. {
    163. case RH: // RR型
    164. pRoot->BF = pRight->BF = EH;
    165. LeftRotation(pRoot);
    166. break;
    167. case LH: // RL型
    168. pRightLeft = pRight->lchild;
    169. switch(pRightLeft->BF)
    170. {
    171. case LH:
    172. pRoot->BF = EH;
    173. pRight->BF = RH;
    174. break;
    175. case EH:
    176. pRoot->BF = EH;
    177. pRight->BF = EH;
    178. break;
    179. case RH:
    180. pRoot->BF = LH;
    181. pRight->BF = EH;
    182. break;
    183. }
    184. pRightLeft->BF = EH;
    185. RightRotation(pRoot->rchild);
    186. LeftRotation(pRoot);
    187. break;
    188. }
    189. }

     

  • 相关阅读:
    Http状态码
    一起备战蓝桥杯与CCF-CSP之大模拟炉石传说
    Vulkan SDK 中的 demo 编译配置 win10 vs2019
    Kotlin协程:生命周期原理
    当我开始刻意不工作
    长城新能源汽车,战力已蓄满
    【C++红黑树】带图详细解答红黑树的插入,测试自己的红黑树是否正确的代码
    Uni-app 小程序 APP 的广告变现之路:小程序插件
    力扣用队列实现栈
    denied: requested access to the resource is denied报错解决
  • 原文地址:https://blog.csdn.net/atm7758258/article/details/136483133