• 数据结构-AVL树(平衡二叉树)


    目录

    AVL树的概念及结构

    概念

    结构

    AVL树的插入

    右旋转

    左旋转

    左右双旋

    右左旋转 

    AVL树的删除 

    插入与删除的总结 

    AVL树的基本操作

    构造

    析构

    = 重载

    [ ] 重载

    中序遍历

    判断一棵树是否为AVL树

    代码


    AVL树的概念及结构

    概念

       对于普通二叉搜索树,如果在数据有序或者接近有序时插入删除,二叉搜索树会退化成单支树,也就是类似单链表的结构;因此为了避免普通二叉搜索树的高度增长过快,降低二叉搜索树的效率与性能。

       规定在插入和删除二叉搜索树的结点时,要保证任意结点的左右子树高度差的绝对值不超过1,我们将这样特殊的二叉搜索树称为AVL树(平衡二叉树)。每一个结点中有记录其左右子树高度差的平衡因子,也即平衡因子的值只可能是-1,0,1。(1如果某结点的左子树高度比右子树高度高一则平衡因子为-1,如果某结点的左子树高度比右子树高度低一则平衡因子为1,如果某结点的左子树高度与右子树高度一样则平衡因子为0)。

       AVL树有以下性质:

    1,每个结点的左右子树都是AVL树

    2,左子树与右子树的高度差只能为-1,0,1(规定平衡因子等于右子树的高度减左子树的高度)

    3,如果AVL树非常平衡,则整体结构接近满二叉树,所以当结点为N个时,其高度为log(2)N

    结构

       为了便于更新平衡因子与旋转处理AVL树的链式结构采用三叉链,也就是AVL树的每个结点都包含:双亲结点地址,左孩子地址,右孩子地址,平衡因子,KV数据。

    AVL树的插入

    第一步:按照二叉搜索树的插入操作进行新结点的插入,但需要注意的是要将新插入结点中的_parent指向改为其双亲。

    第二步:更新平衡因子,从插入结点的双亲开始往上更新;如果插入的结点是双亲的右孩子则双亲的平衡因子--,如果插入的结点是双亲的左孩子则双亲的平衡因子++;更新过的平衡因子有三种情况:

    1,如果平衡因子变为0,则说明原来的平衡因子为-1或者1,也就是原来左右子树的高度差绝对值为1,经过插入新结点,使该结点的左右子树达到平衡,所以无须继续往上更新平衡因子。

    2,如果平衡因子变为-1或者1,则说明原来的平衡因子为0,也就是原来左右子树的高度一致,经过插入新结点,使该结点的左右子树的高度差绝对值变为1,所以需要继续往上更新平衡因子。

    3,如果平衡因子变为-2或者2,则说明原来的平衡因子为-1或者1,也就是原来左右子树高度差绝对值为1,经过插入新结点,使该结点的左右子树高度差绝对值为2,造成不满足AVL树性质要求需要进行旋转处理。

    第三步:旋转处理,使不平衡的AVL树变为平衡的AVL树;造成平衡的AVL树变为不平衡的AVL树的原因有4种,也就是说使不平衡的AVL树变为平衡的AVL树的旋转处理方式也有4种,每一种原因对应一种旋转处理方式。

    右旋转

       在A结点的左孩子B的左子树上插入新结点,导致以A为根的子树失去平衡(左子树比右子树高),需要进行右旋转处理

    右旋转的具体操作:先让B结点的_right指向A结点,再让A结点的_left指向原B结点的右子树b。

    左旋转

       在A结点的右孩子B的右子树上插入新结点,导致以A为根的子树失去平衡(左子树比右子树低),需要进行左旋转处理。

    左旋转的具体操作:先让B结点的_left指向A结点,再让A结点的_right指向原B结点的左子树b。

    左右双旋

       由于在A的左孩子B的右子树上插入新结点,A的平衡因子由-1变为-2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先左旋转再右旋转。左旋转是以B结点为轴,右旋转是以A结点为轴。

    具体操作:先将A结点的左孩子B的右子树的根节点C向左上旋转提升到B结点的位置,然后把该C结点向右上旋转提升到A结点的位置。

    1. // 左右旋
    2. void RotateLR(Node* parrnt)
    3. {
    4. Node* subL = parrnt->_left;
    5. Node* subLR = subL->_right;
    6. short bf = subLR->_bf;
    7. RotateL(parrnt->_left);
    8. RotateR(parrnt);
    9. if (bf == 1)
    10. {
    11. subLR->_bf = 0;
    12. subL->_bf = -1;
    13. parrnt->_bf = 0;
    14. }
    15. else if (bf == -1)
    16. {
    17. subLR->_bf = 0;
    18. subL->_bf = 0;
    19. parrnt->_bf = 1;
    20. }
    21. else if(bf==0)
    22. {
    23. subLR->_bf = 0;
    24. subL->_bf = 0;
    25. parrnt->_bf = 0;
    26. }
    27. else
    28. {
    29. assert(false);
    30. }
    31. }

    右左旋转 

       由于在A的右孩子B的左子树上插入新结点,A的平衡因子由1变为2,导致以A为根的子树失去平衡,需要进行两次旋转操作,先右旋转在左旋转。右旋转是以B结点为轴,左旋转是以A结点为轴。

    具体操作:先将A结点的右孩子B的左子树的根节点C向右上旋转提升到B结点的位置,然后把该C结点向左上旋转提升到A结点的位置。

    1. // 右左旋
    2. void RotateRL(Node* parent)
    3. {
    4. Node* subR = parent->_right;
    5. Node* subRL = subR->_left;
    6. short bf = subRL->_bf;
    7. RotateR(parent->_right);
    8. RotateL(parent);
    9. if (bf == 1)
    10. {
    11. subRL->_bf = 0;
    12. subR->_bf = 0;
    13. parent->_bf = -1;
    14. }
    15. else if (bf==-1)
    16. {
    17. subRL->_bf = 0;
    18. subR->_bf = 1;
    19. parent->_bf = 0;
    20. }
    21. else if(bf==0)
    22. {
    23. subRL->_bf = 0;
    24. subR->_bf = 0;
    25. parent->_bf = 0;
    26. }
    27. else
    28. {
    29. assert(false);
    30. }
    31. }

    AVL树的删除 

    第一步:先找到要删除的结点

    第二步:按照要删除结点的类型进行分类删除:1,左子树为空   2,右子树为空   3,左右子树都为空   4,左右子树都不为空

    第三步:更新平衡因子。如果删除的结点在其双亲的左边则双亲的平衡因子++,如果删除的结点在其双亲结点的右边则双亲的平衡因子--。

    1,如果更新后parent->_bf==0,说明parent->_bf原来是-1或者1,把高的那边删除掉了,高度变小了,继续往上更新。

    2,如果更新后parent->_bf==-1或者parenr->_bf==1,说明parent->_bf原来是0,删除了其左右结点其中的一个,高度没有变,不需要继续往上更新。

    3,如果更新后parent->_bf==-2或者parenr->_bf==2,说明AVL树不平衡,需要旋转处理。

    第四步:旋转处理。

    // 旋转规则(有四种情况):

    // firstDepth是parent高度最高的孩子结点,secondDepth是firstDepth高度最后的结点
    // 1,如果first是parent的左孩子,second是first的左孩子---右旋转
    // 2,如果first是parent的左孩子,second是first的右孩子---左右双旋

    // 3,如果first是parent的右孩子,second是first的右孩子---左旋转

    // 4,如果first是parent的右孩子,second是first的左孩子---右左双旋

    插入与删除的总结 

    AVL树的基本操作

    构造

    1. // 无参构造
    2. AVLTree()
    3. :_root(nullptr)
    4. {
    5. }
    1. // 拷贝构造
    2. Node* _CopyAVLTree(Node* root, Node* parent)
    3. {
    4. if (root == nullptr)
    5. {
    6. return nullptr;
    7. }
    8. Node* newNode = new Node(root->_kv);
    9. newNode->_bf = root->_bf;
    10. newNode->_parent = parent;
    11. newNode->_left = _CopyAVLTree(root->_left,newNode);
    12. newNode->_right = _CopyAVLTree(root->_right,newNode);
    13. return newNode;
    14. }
    15. AVLTree(const AVLTree& t)
    16. {
    17. _root=_CopyAVLTree(t._root, nullptr);
    18. }

    析构

    1. //析构
    2. ~AVLTree()
    3. {
    4. _Destroy(_root);
    5. _root = nullptr;
    6. }
    7. //销毁
    8. void _Destroy(Node* root)
    9. {
    10. if (root == nullptr)
    11. {
    12. return;
    13. }
    14. _Destroy(root->_left);
    15. _Destroy(root->_right);
    16. delete root;
    17. }

    = 重载

    1. AVLTree& operator=(AVLTree t)
    2. {
    3. swap(_root, t._root);
    4. return *this;
    5. }

    [ ] 重载

    1. V& operator[](const K& key)
    2. {
    3. pairbool> ret = Insert(make_pair(key,V()));
    4. return (ret.first)->_kv.second;
    5. }

    中序遍历

    1. void InOrder()
    2. {
    3. _InOrder(_root);
    4. cout << endl;
    5. }

    判断一棵树是否为AVL树

    1. bool IsAVLTree()
    2. {
    3. return _IsAVLTree(_root);
    4. }

    代码

    1. // .hpp
    2. #pragma once
    3. #include
    4. #include
    5. using namespace std;
    6. template <class K,class V>
    7. struct AVLTreeNode
    8. {
    9. short _bf; // 平衡因子---记录其左右子树的高度差(右子树高度减左子树高度)
    10. struct AVLTreeNode* _parent; // 记录其双亲的地址
    11. struct AVLTreeNode* _left; // 记录其左孩子的地址
    12. struct AVLTreeNode* _right; // 记录其右孩子的地址
    13. pair _kv; // kv值
    14. AVLTreeNode(const pair& kv)
    15. :_bf(0)
    16. ,_parent(nullptr)
    17. ,_left(nullptr)
    18. ,_right(nullptr)
    19. ,_kv(kv)
    20. {
    21. }
    22. };
    23. template <class K,class V>
    24. class AVLTree
    25. {
    26. typedef struct AVLTreeNode Node;
    27. private:
    28. Node* _root;
    29. // 左旋转---左子树低
    30. void RotateL(Node* parent) // parent是平衡因子为-2或者2的结点
    31. {
    32. Node* parentParent = parent->_parent; // 记录其双亲
    33. Node* subR = parent->_right; // 记录其右孩子
    34. Node* subRL = subR->_left; // 记录其右孩子的左孩子
    35. // 让subR的左孩子指向parent,parent的双亲指向subR
    36. subR->_left = parent;
    37. parent->_parent = subR;
    38. // 让parent的右孩子指向subR的左孩子
    39. parent->_right = subRL;
    40. if (subRL) // 如果subRL不为空,则让subR的左孩子的_parent指向parent
    41. {
    42. subRL->_parent = parent;
    43. }
    44. // 更新parent的双亲结点中的左孩子或者右孩子指向,并更新subR的_parent的指向
    45. if (parent == _root)
    46. {
    47. _root = subR;
    48. subR->_parent = nullptr;
    49. }
    50. else
    51. {
    52. if (parentParent->_left == parent)
    53. {
    54. parentParent->_left = subR;
    55. }
    56. else if(parentParent->_right==parent)
    57. {
    58. parentParent->_right = subR;
    59. }
    60. subR->_parent = parentParent;
    61. }
    62. // 更新旋转处理后的平衡因子
    63. parent->_bf = 0;
    64. subR->_bf = 0;
    65. }
    66. // 右旋转
    67. void RotateR(Node* parent) // parent是平衡因子为-2或者2的结点
    68. {
    69. Node* parentParent = parent->_parent; // 记录其双亲
    70. Node* subL = parent->_left; // 记录其左孩子
    71. Node* subLR = subL->_right; // 记录其左孩子的右孩子
    72. // parent的双亲指向subL,subL的右孩子指向parent
    73. parent->_parent = subL;
    74. subL->_right = parent;
    75. // parent的左孩子指向subL的右孩子
    76. parent->_left = subLR;
    77. if (subLR) // 如果subLR不为空,则让subLR的双亲指向parent
    78. {
    79. subLR->_parent = parent;
    80. }
    81. if (_root == parent) // parent的双亲为空则说明parent是整棵树的根节点
    82. {
    83. _root = subL; // 让subL当整棵树的根节点
    84. subL->_parent = nullptr; // 并让subL的双亲指向空
    85. }
    86. else // 否则parent是某棵子树的根节点,更新parentParent左孩子或者右孩子的指向
    87. {
    88. if (parentParent->_left == parent)
    89. {
    90. parentParent->_left = subL;
    91. }
    92. else
    93. {
    94. parentParent->_right = subL;
    95. }
    96. subL->_parent = parentParent; // 更新subL双亲的指向
    97. }
    98. parent->_bf = subL->_bf = 0; // 经过旋转更新平衡因子
    99. }
    100. // 左右旋
    101. void RotateLR(Node* parrnt)
    102. {
    103. Node* subL = parrnt->_left;
    104. Node* subLR = subL->_right;
    105. short bf = subLR->_bf;
    106. RotateL(parrnt->_left);
    107. RotateR(parrnt);
    108. if (bf == 1)
    109. {
    110. subLR->_bf = 0;
    111. subL->_bf = -1;
    112. parrnt->_bf = 0;
    113. }
    114. else if (bf == -1)
    115. {
    116. subLR->_bf = 0;
    117. subL->_bf = 0;
    118. parrnt->_bf = 1;
    119. }
    120. else if(bf==0)
    121. {
    122. subLR->_bf = 0;
    123. subL->_bf = 0;
    124. parrnt->_bf = 0;
    125. }
    126. else
    127. {
    128. assert(false);
    129. }
    130. }
    131. // 右左旋
    132. void RotateRL(Node* parent)
    133. {
    134. Node* subR = parent->_right;
    135. Node* subRL = subR->_left;
    136. short bf = subRL->_bf;
    137. RotateR(parent->_right);
    138. RotateL(parent);
    139. if (bf == 1)
    140. {
    141. subRL->_bf = 0;
    142. subR->_bf = 0;
    143. parent->_bf = -1;
    144. }
    145. else if (bf==-1)
    146. {
    147. subRL->_bf = 0;
    148. subR->_bf = 1;
    149. parent->_bf = 0;
    150. }
    151. else if(bf==0)
    152. {
    153. subRL->_bf = 0;
    154. subR->_bf = 0;
    155. parent->_bf = 0;
    156. }
    157. else
    158. {
    159. assert(false);
    160. }
    161. }
    162. // parent为删除结点的双亲,child为删除的结点
    163. void UpdateBF(Node* parent,Node* child)
    164. {
    165. while (parent != nullptr)
    166. {
    167. if (parent->_left == child)
    168. {
    169. parent->_bf++;
    170. }
    171. else if (parent->_right == child)
    172. {
    173. parent->_bf--;
    174. }
    175. // 检查平衡因子是否异常
    176. if (parent->_bf == 0)
    177. {
    178. child = parent;
    179. parent = parent->_parent;
    180. }
    181. else if (parent->_bf == 1 || parent->_bf == -1)
    182. {
    183. break;
    184. }
    185. else if (parent->_bf == 2 || parent->_bf == -2)
    186. {
    187. // 求出平衡因子异常结点的左右子树中高的那一棵子树
    188. Node* firstDepth = parent->_left;
    189. int maxDepth = AVLTreeDepth(parent->_left);
    190. int minDepth = AVLTreeDepth(parent->_right);
    191. if (maxDepth < minDepth)
    192. {
    193. firstDepth = parent->_right;
    194. }
    195. // 求出firstDepth结点的左右子树中高的那一棵子树
    196. Node* secondDepth = firstDepth->_left;
    197. maxDepth = AVLTreeDepth(firstDepth->_left);
    198. minDepth = AVLTreeDepth(firstDepth->_right);
    199. if (maxDepth < minDepth)
    200. {
    201. secondDepth = firstDepth->_right;
    202. }
    203. // 旋转规则(有四种情况):
    204. // firstDepth是parent高度最高的孩子结点,secondDepth是firstDepth高度最后的结点
    205. // 1,如果first是parent的左孩子,second是first的左孩子---右旋转
    206. // 2,如果first是parent的左孩子,second是first的右孩子---左右双旋
    207. // 3,如果first是parent的右孩子,second是first的右孩子---左旋转
    208. // 4,如果first是parent的右孩子,second是first的左孩子---右左双旋
    209. if (parent->_left == firstDepth)
    210. {
    211. if (firstDepth->_left == secondDepth)
    212. {
    213. RotateR(parent);
    214. }
    215. else if (firstDepth->_right == secondDepth)
    216. {
    217. RotateLR(parent);
    218. }
    219. }
    220. else if (parent->_right == firstDepth)
    221. {
    222. if (firstDepth->_left == secondDepth)
    223. {
    224. RotateRL(parent);
    225. }
    226. else if (firstDepth->_right == secondDepth)
    227. {
    228. RotateL(parent);
    229. }
    230. }
    231. break;
    232. }
    233. else
    234. {
    235. assert(false);
    236. }
    237. }
    238. }
    239. void _InOrder(Node* root)
    240. {
    241. if (root == nullptr)
    242. {
    243. return;
    244. }
    245. _InOrder(root->_left);
    246. cout << " K:" << root->_kv.first << " V:" << root->_kv.second << " bf:" << root->_bf <
    247. _InOrder(root->_right);
    248. }
    249. // 判断是否为AVL树
    250. bool _IsAVLTree(Node* root)
    251. {
    252. if (root == nullptr)
    253. {
    254. return true;
    255. }
    256. int left = AVLTreeDepth(root->_left);
    257. int right = AVLTreeDepth(root->_right);
    258. return abs(left - right) < 2 && _IsAVLTree(root->_left) && _IsAVLTree(root->_right);
    259. }
    260. // 拷贝构造
    261. Node* _CopyAVLTree(Node* root, Node* parent)
    262. {
    263. if (root == nullptr)
    264. {
    265. return nullptr;
    266. }
    267. Node* newNode = new Node(root->_kv);
    268. newNode->_bf = root->_bf;
    269. newNode->_parent = parent;
    270. newNode->_left = _CopyAVLTree(root->_left,newNode);
    271. newNode->_right = _CopyAVLTree(root->_right,newNode);
    272. return newNode;
    273. }
    274. //销毁
    275. void _Destroy(Node* root)
    276. {
    277. if (root == nullptr)
    278. {
    279. return;
    280. }
    281. _Destroy(root->_left);
    282. _Destroy(root->_right);
    283. delete root;
    284. }
    285. public:
    286. AVLTree()
    287. :_root(nullptr)
    288. {
    289. }
    290. AVLTree(const AVLTree& t)
    291. {
    292. _root=_CopyAVLTree(t._root, nullptr);
    293. }
    294. ~AVLTree()
    295. {
    296. _Destroy(_root);
    297. _root = nullptr;
    298. }
    299. V& operator[](const K& key)
    300. {
    301. pairbool> ret = Insert(make_pair(key,V()));
    302. return (ret.first)->_kv.second;
    303. }
    304. AVLTree& operator=(AVLTree t)
    305. {
    306. swap(_root, t._root);
    307. return *this;
    308. }
    309. pairbool> Insert(const pair& kv)
    310. {
    311. if (_root == nullptr) // 若AVL为空树,则直接插入
    312. {
    313. _root = new Node(kv);
    314. return make_pair(_root,true);
    315. }
    316. Node* prev = nullptr; // 记录插入结点所在路径的最后一个结点
    317. Node* curr = _root; // 引导prev走到最后一个结点
    318. // 寻找插入位置
    319. while (curr)
    320. {
    321. if (curr->_kv.first > kv.first) // 要插入的值比较小,往左走
    322. {
    323. prev = curr;
    324. curr = curr->_left;
    325. }
    326. else if (curr->_kv.first < kv.first) // 要插入的值比根结点的值大,往右走
    327. {
    328. prev = curr;
    329. curr = curr->_right;
    330. }
    331. else // 要插入的值比根结点的值大,则插入失败
    332. {
    333. return make_pair(curr,false);
    334. }
    335. }
    336. // 开始插入
    337. curr = new Node(kv);
    338. Node* ret = curr;
    339. if (prev->_kv.first > kv.first) // 左插入
    340. {
    341. prev->_left = curr;
    342. curr->_parent = prev; //
    343. }
    344. else if (prev->_kv.first < kv.first) // 右插入
    345. {
    346. prev->_right = curr;
    347. curr->_parent = prev; //
    348. }
    349. // 更新平衡因子---将新插入结点curr的祖先的平衡因子更新
    350. // while(curr!=_root)
    351. while (prev != nullptr)
    352. {
    353. if (prev->_left == curr)
    354. {
    355. prev->_bf--; // 如果是往其左子树插入,则_bf--;
    356. }
    357. else if (prev->_right == curr)
    358. {
    359. prev->_bf++; // 如果是往其右子树插入,则_bf++;
    360. }
    361. if (prev->_bf == 0) // 左右子树达到平衡,不需要继续往上更新平衡因子
    362. {
    363. break;
    364. }
    365. else if (prev->_bf == 1 || prev->_bf == -1) // 需要继续往上更新平衡因子
    366. {
    367. curr = prev;
    368. prev = prev->_parent;
    369. }
    370. else if (prev->_bf == 2 || prev->_bf == -2) // 左右子树不平衡,需要继续旋转调整
    371. {
    372. if (prev->_bf == 2)
    373. {
    374. if (curr->_bf == 1) // 右子树高---右结点的右子树上插入
    375. {
    376. RotateL(prev); // 左旋转
    377. }
    378. else if (curr->_bf == -1) // 右子树高---右结点的左子树上插入
    379. {
    380. RotateRL(prev); // 先右旋再左旋
    381. }
    382. }
    383. else
    384. {
    385. if (curr->_bf == 1) // 左子树高---左结点的右子树上插入
    386. {
    387. RotateLR(prev); // 先左旋再右旋
    388. }
    389. else if (curr->_bf == -1) // 左子树高---左结点的左子树上插入
    390. {
    391. RotateR(prev);
    392. }
    393. }
    394. break;
    395. }
    396. else
    397. {
    398. assert(false);
    399. }
    400. }
    401. return make_pair(ret, true);
    402. }
    403. bool Erase(const pair& kv)
    404. {
    405. if (_root == nullptr)
    406. {
    407. return false;
    408. }
    409. Node* prev = _root;
    410. Node* curr = _root;
    411. while (curr)
    412. {
    413. if (curr->_kv.first > kv.first)
    414. {
    415. prev = curr;
    416. curr = curr->_left;
    417. }
    418. else if (curr->_kv.first < kv.first)
    419. {
    420. prev = curr;
    421. curr = curr->_right;
    422. }
    423. else
    424. {
    425. if (curr->_left == nullptr)
    426. {
    427. if (prev == _root)
    428. {
    429. _root = curr->_right;
    430. if (curr->_right)
    431. {
    432. curr->_right->_parent = _root;
    433. }
    434. delete curr;
    435. return true;
    436. }
    437. else
    438. {
    439. UpdateBF(prev, curr);
    440. if (prev->_left == curr)
    441. {
    442. prev->_left = curr->_right;
    443. if (curr->_right)
    444. {
    445. curr->_right->_parent = prev->_left;
    446. }
    447. }
    448. else
    449. {
    450. prev->_right = curr->_right;
    451. if (curr->_right)
    452. {
    453. curr->_right->_parent = prev->_right;
    454. }
    455. }
    456. delete curr;
    457. return true;
    458. }
    459. }
    460. else if (curr->_right == nullptr)
    461. {
    462. if (prev == _root)
    463. {
    464. _root = curr->_left;
    465. if (curr->_left)
    466. {
    467. curr->_left->_parent = _root;
    468. }
    469. delete curr;
    470. return true;
    471. }
    472. else
    473. {
    474. UpdateBF(prev, curr);
    475. if (prev->_left == curr)
    476. {
    477. prev->_left = curr->_left;
    478. if (curr->_left)
    479. {
    480. curr->_left->_parent = prev->_left;
    481. }
    482. }
    483. else
    484. {
    485. prev->_right = curr->_left;
    486. if (curr->_left)
    487. {
    488. curr->_left->_parent = prev->_right;
    489. }
    490. }
    491. delete curr;
    492. return true;
    493. }
    494. }
    495. else
    496. {
    497. Node* min = curr->_right;
    498. while (min->_left)
    499. {
    500. min = min->_left;
    501. }
    502. pair tmp = min->_kv;
    503. Erase(tmp);
    504. curr->_kv = tmp;
    505. return true;
    506. }
    507. }
    508. }
    509. return false;
    510. }
    511. void InOrder()
    512. {
    513. _InOrder(_root);
    514. cout << endl;
    515. }
    516. Node* Find(const K& key)
    517. {
    518. Node* curr = _root;
    519. while (curr)
    520. {
    521. if (curr->_kv.first > key)
    522. {
    523. curr = curr->_left;
    524. }
    525. else if (curr->_kv.first < key)
    526. {
    527. curr = curr->_right;
    528. }
    529. else
    530. {
    531. return curr;
    532. }
    533. }
    534. return nullptr;
    535. }
    536. int AVLTreeDepth(Node* root)
    537. {
    538. if (root == nullptr)
    539. {
    540. return 0;
    541. }
    542. int leftDepth = AVLTreeDepth(root->_left);
    543. int rightDepth = AVLTreeDepth(root->_right);
    544. return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
    545. }
    546. bool IsAVLTree()
    547. {
    548. return _IsAVLTree(_root);
    549. }
    550. };

  • 相关阅读:
    Ubuntu下安装anaconda流程
    计算机毕业设计Java江西婺源旅游文化推广系统(源码+系统+mysql数据库+lw文档)
    〖Python APP 自动化测试实战篇②〗 - 大话闲扯 APP 自动化工具的演进史
    Java 中的 void 和 Kotlin 的 Unit
    如何快速定位 dpdk memzone 内存泄露问题?
    Java版分布式微服务云开发架构 Spring Cloud+Spring Boot+Mybatis 电子招标采购系统功能清单
    CSS 伪类选择器 last-child 和 last-of-type 的区别
    概率论与数理统计
    Leetcode.4 寻找两个正序数组的中位数
    我国农业科学数据共享协议
  • 原文地址:https://blog.csdn.net/m0_61433144/article/details/126292579