当前位置:   article > 正文

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

avl树

目录

AVL树的概念及结构

概念

结构

AVL树的插入

右旋转

左旋转

左右双旋

右左旋转 

AVL树的删除 

插入与删除的总结 

AVL树的基本操作

构造

析构

= 重载

[ ] 重载

中序遍历

判断一棵树是否为AVL树

代码


AVL树的概念及结构

概念

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

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

   AVL树有以下性质:

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

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

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

结构

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

AVL树的插入

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

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

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

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

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

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

右旋转

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

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

5746e220e2974c7999a8de1b16dfa96a.png

左旋转

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

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

149071fff2894e62ad5e1e9aee208cd7.png

左右双旋

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

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

  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结点为轴。8ca2556db2b14b21ad8587483c7b5e7a.png

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

  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树的删除 

第一步:先找到要删除的结点78140275f2144466b126fb504fcd582d.png

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

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

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的左孩子---右左双旋

86a5e39870b64ee7a155cfd8da299ea3.png

8d82e9aeb5264073b720d3cd74ac4d25.png

插入与删除的总结 

9b376f7e76b940e9bb904c6f48b3cdde.png

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. pair<Node*, bool> ret = Insert(make_pair(key,V()));
  4. return (ret.first)->_kv.second;
  5. }

中序遍历

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

e6f272e3b9c64604b8e22454508728fb.png

判断一棵树是否为AVL树

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

99b4290d2dda4f7ab36487340742b263.png

代码

  1. // .hpp
  2. #pragma once
  3. #include <iostream>
  4. #include <cassert>
  5. using namespace std;
  6. template <class K,class V>
  7. struct AVLTreeNode
  8. {
  9. short _bf; // 平衡因子---记录其左右子树的高度差(右子树高度减左子树高度)
  10. struct AVLTreeNode<K, V>* _parent; // 记录其双亲的地址
  11. struct AVLTreeNode<K, V>* _left; // 记录其左孩子的地址
  12. struct AVLTreeNode<K, V>* _right; // 记录其右孩子的地址
  13. pair<K, V> _kv; // kv值
  14. AVLTreeNode(const pair<K,V>& 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<K, V> 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 <<endl;
  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. pair<Node*, bool> 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. pair<Node*,bool> Insert(const pair<K, V>& 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<K, V>& kv)
  404. {
  405. if (_root == nullptr) // 如果AVL树为空则不需要删除
  406. {
  407. return false;
  408. }
  409. Node* prev = nullptr; // 记录删除结点的双亲
  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 == nullptr) // 删除根结点
  428. {
  429. _root = curr->_right;
  430. if (curr->_right)
  431. {
  432. curr->_right->_parent = nullptr;
  433. }
  434. }
  435. else // 删除非根结点
  436. {
  437. UpdateBF(prev, curr); // 删除之前调整平衡因子
  438. if (prev->_left == curr)
  439. {
  440. prev->_left = curr->_right;
  441. }
  442. else
  443. {
  444. prev->_right = curr->_right;
  445. }
  446. if (curr->_right)
  447. {
  448. curr->_right->_parent = prev;
  449. }
  450. }
  451. delete curr;
  452. return true;
  453. }
  454. else if (curr->_right == nullptr) // 删除结点的右子树为空
  455. {
  456. if (prev == nullptr) // 删除根结点,更新_root
  457. {
  458. _root = curr->_left;
  459. if (curr->_left)
  460. {
  461. curr->_left->_parent = nullptr;
  462. }
  463. }
  464. else // 删除非根结点
  465. {
  466. UpdateBF(prev, curr);
  467. if (prev->_left == curr)
  468. {
  469. prev->_left = curr->_left;
  470. }
  471. else
  472. {
  473. prev->_right = curr->_left;
  474. }
  475. if (curr->_left)
  476. {
  477. curr->_left->_parent = prev;
  478. }
  479. }
  480. delete curr;
  481. return true;
  482. }
  483. else // 删除结点的左右子树都不为空
  484. {
  485. Node* min = curr->_right;
  486. while (min->_left)
  487. {
  488. min = min->_left;
  489. }
  490. pair<K, V> tmp = min->_kv;
  491. Erase(tmp); // 替换删除
  492. curr->_kv = tmp;
  493. return true;
  494. }
  495. }
  496. }
  497. return false;
  498. }
  499. void InOrder()
  500. {
  501. _InOrder(_root);
  502. cout << endl;
  503. }
  504. Node* Find(const K& key)
  505. {
  506. Node* curr = _root;
  507. while (curr)
  508. {
  509. if (curr->_kv.first > key)
  510. {
  511. curr = curr->_left;
  512. }
  513. else if (curr->_kv.first < key)
  514. {
  515. curr = curr->_right;
  516. }
  517. else
  518. {
  519. return curr;
  520. }
  521. }
  522. return nullptr;
  523. }
  524. int AVLTreeDepth(Node* root)
  525. {
  526. if (root == nullptr)
  527. {
  528. return 0;
  529. }
  530. int leftDepth = AVLTreeDepth(root->_left);
  531. int rightDepth = AVLTreeDepth(root->_right);
  532. return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
  533. }
  534. bool IsAVLTree()
  535. {
  536. return _IsAVLTree(_root);
  537. }
  538. };

 

 

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

闽ICP备14008679号