当前位置:   article > 正文

AVL树_avl tree全称

avl tree全称

AVL树全称高度平衡二叉树,它是一种优化了的搜索二叉树。我们知道,由于搜索二叉树存在缺陷,有可能退化成单链,这样的话搜索效率就降低了。为了将二叉搜索树的效率控制在O(logN),所以对二叉搜索树加上一些条件,使得二叉搜索树高度平衡,时间复杂度为O(log N).

一   定义:

           1.首先AVL树是一个二叉搜索树

           2.它的左子树,右子数都是AVL树

           3.它的左子树和右子数的高度差不超过1.(通常情况下,为每个结点都加一个平衡因子bf,这个平衡因子是右子树的高度减去左子树高度)

二  平衡化旋转

如果一棵树原来是平衡的二叉搜索树,现在向里面添加一个结点。造成了不平衡。这时候我们就要调整这棵树的结构,使之重新平衡。以下是造成树不平衡的结构有哪些,以及如何调整。

下面关于平衡的几点,需要注意:

              1.所有的插入都是建立在平衡二叉树的基础上的

              2.如果插入一个结点,树的高度不变,则它就是平衡的

              3.插入之后会影响从插入点到根节点路径上结点的平衡因子

            4. 平衡因子的取值只可能是0,1,-1,2,-2.当为-2或2时就出现不平衡了,这时就需要旋转,旋转后树就平衡了。(注                 意旋转后树平衡的原因是通过旋转使树的高度降下来了,和之前相同,因此树平衡了)
        
关于左右双旋平衡因子更新,有以下三种情况

  1. #include<iostream>
  2. #include<assert.h>
  3. using namespace std;
  4. template<class V>
  5. struct AVLTreeNode
  6. {
  7. V _value;
  8. int _bf;//平衡因子右子树的高度减去左子树的高度
  9. AVLTreeNode< V>* _left;
  10. AVLTreeNode< V>* _right;
  11. AVLTreeNode< V>* _parent;
  12. AVLTreeNode( const V& value)
  13. :_value(value)
  14. , _bf(0)
  15. , _left(NULL)
  16. , _right(NULL)
  17. , _parent(NULL)
  18. {}
  19. };
  20. template<class V>
  21. class AVLTree
  22. {
  23. typedef AVLTreeNode< V> Node;
  24. public:
  25. AVLTree()
  26. :_root(NULL)
  27. {}
  28. AVLTree(const AVLTree< V>& t)
  29. {
  30. _root = _Copy(t._root);
  31. }
  32. AVLTree< V>& operator=(const AVLTree< V>& t)//现代写法
  33. {
  34. if (this != &t)
  35. {
  36. AVLTree<K, V> tmp(t);
  37. swap(tmp._root, _root);
  38. }
  39. return *this;
  40. }
  41. /*AVLTree< V>& operator=(const AVLTree< V> t)
  42. {
  43. swap(_root, t._root);
  44. return *this;
  45. }*/
  46. ~AVLTree()
  47. {
  48. _Destory(_root);
  49. }
  50. bool Isbalance()
  51. {
  52. //return _Isbalance(_root);
  53. int height = 0;
  54. return _IsbalanceOP(_root, height);
  55. }
  56. bool Insert( V& value)
  57. {
  58. Node* cur = _root;
  59. Node* parent = NULL;
  60. if (_root == NULL)
  61. {
  62. _root = new Node( value);
  63. return true;
  64. }
  65. while (cur)
  66. {
  67. if (cur->_value < value)
  68. {
  69. parent = cur;
  70. cur = cur->_right;
  71. }
  72. else if (cur->_value>value)
  73. {
  74. parent = cur;
  75. cur = cur->_left;
  76. }
  77. else
  78. {
  79. return false;
  80. }
  81. }
  82. cur = new Node(value);
  83. if (parent->_value>value)
  84. {
  85. parent->_left = cur;
  86. cur->_parent = parent;
  87. }
  88. else
  89. {
  90. parent->_right = cur;
  91. cur->_parent = parent;
  92. }
  93. while (parent)//更新平衡因子
  94. {
  95. if (parent->_left ==cur)
  96. {
  97. parent->_bf--;
  98. }
  99. else
  100. {
  101. parent->_bf++;
  102. }
  103. if (parent->_bf == 0)//当父亲结点的平衡因子为0,说明插入之后树高度不变仍然平衡
  104. {
  105. return true;
  106. }
  107. else if (parent->_bf == 1 || parent->_bf == -1)//本次不违反规则,但是会影响根节点到parent路径上其他结点的平衡,因此继续向上更新
  108. {
  109. cur = parent;
  110. parent = parent->_parent;
  111. }
  112. else if (parent->_bf == 2 || parent->_bf == -2)//已经违反平衡规则,不再更新,直接旋转
  113. {
  114. if (parent->_bf == 2)
  115. {
  116. if (cur->_bf == 1)
  117. {
  118. _RotateL(parent);
  119. return true;
  120. }
  121. else
  122. {
  123. _RotateRL(parent);
  124. return true;
  125. }
  126. }
  127. if (parent->_bf == -2)
  128. {
  129. if (cur->_bf == -1)
  130. {
  131. _RotateR(parent);
  132. return true;
  133. }
  134. else
  135. {
  136. _RotateLR(parent);
  137. return true;
  138. }
  139. }
  140. }
  141. }
  142. return true;
  143. }
  144. void _RotateR(Node* parent)
  145. {
  146. assert(parent);
  147. Node* SubL = parent->_left;
  148. Node* SubLR = SubL->_right;
  149. Node* ppNode = parent->_parent;
  150. parent->_left = SubLR;
  151. if (SubLR)
  152. {
  153. SubLR->_parent = parent;
  154. }
  155. SubL->_right = parent;
  156. parent->_parent = SubL;
  157. if (ppNode==NULL)
  158. {
  159. _root = SubL;
  160. SubL->_parent = NULL;
  161. }
  162. else
  163. {
  164. if (ppNode->_left == parent)
  165. {
  166. ppNode->_left = SubL;
  167. }
  168. else
  169. {
  170. ppNode->_right = SubL;
  171. }
  172. SubL->_parent = ppNode;
  173. }
  174. parent->_bf = SubL->_bf = 0;
  175. }
  176. void _RotateL(Node *parent)
  177. {
  178. assert(parent);
  179. Node* SubR = parent->_right;
  180. Node* SubRL = SubR->_left;
  181. Node* ppNode = parent->_parent;
  182. parent->_right = SubRL;
  183. if (SubRL)
  184. {
  185. SubRL->_parent = parent;
  186. }
  187. SubR->_left = parent;
  188. parent->_parent = SubR;
  189. if (ppNode == NULL)
  190. {
  191. _root = SubR;
  192. SubR->_parent = NULL;
  193. }
  194. else
  195. {
  196. if (ppNode->_left == parent)
  197. {
  198. ppNode->_left = SubR;
  199. }
  200. else
  201. {
  202. ppNode->_right = SubR;
  203. }
  204. SubR->_parent = ppNode;
  205. }
  206. parent->_bf = SubR->_bf = 0;
  207. }
  208. void _RotateLR(Node *parent)
  209. {
  210. Node* SubL = parent->_left;
  211. Node* SubLR = SubL->_right;
  212. int bf = SubLR->_bf;//计算旋转以后的根节点的bf
  213. _RotateL(SubL);
  214. _RotateR(parent);
  215. //如果bf为0,代表插入点就是这个结点,这个时候所有旋转后bf皆为0
  216. if (bf == 0)
  217. {
  218. SubL->_bf = parent->_bf = 0;
  219. SubLR->_bf = 0;
  220. }
  221. //当bf为1时,这个时候相当于是在给bf的右树插入,
  222. else if (bf == -1)
  223. {
  224. SubL->_bf = -1;
  225. parent->_bf = 0;
  226. SubLR->_bf = 0;
  227. }
  228. //当bf为-1时,这时相当于给bf的左树进行插入
  229. else
  230. {
  231. SubL->_bf = 0;
  232. parent->_bf = 1;
  233. SubLR->_bf = 0;
  234. }
  235. }
  236. void _RotateRL(Node* parent)
  237. {
  238. Node*SubR = parent->_right;
  239. Node*SubRL = SubR->_left;
  240. int bf = SubRL->_bf;
  241. _RotateR(SubR);
  242. _RotateL(parent);
  243. if (bf == 0)
  244. {
  245. parent->_bf = SubR->_bf = 0;
  246. SubRL->_bf = 0;
  247. }
  248. else if (bf == 1)
  249. {
  250. parent->_bf = -1;
  251. SubR->_bf = 0;
  252. SubRL->_bf = 0;
  253. }
  254. else
  255. {
  256. parent->_bf = 0;
  257. SubR->_bf = 1;
  258. SubRL->_bf = 0;
  259. }
  260. }
  261. size_t Height()
  262. {
  263. return _Height(_root);
  264. }
  265. void Inorder()
  266. {
  267. _Inorder(_root);
  268. cout << endl;
  269. }
  270. protected:
  271. void _Inorder(Node* Root)
  272. {
  273. if (Root == NULL)
  274. {
  275. return;
  276. }
  277. else
  278. {
  279. _Inorder(Root->_left);
  280. cout << Root->_value<<" ";
  281. _Inorder(Root->_right);
  282. }
  283. }
  284. size_t _Height(Node* Root)
  285. {
  286. if (Root == NULL)
  287. {
  288. return 0;
  289. }
  290. else
  291. {
  292. int leftheight = _Height(Root->_left);
  293. int rightheight = _Height(Root->_right);
  294. return leftheight > rightheight ? leftheight + 1 : rightheight + 1;
  295. }
  296. }
  297. Node* _Copy(Node* Root)
  298. {
  299. Node* tmp = NULL;
  300. if (Root!=NULL)
  301. {
  302. tmp = new Node(Root->_value);
  303. tmp->_left = _Copy(Root->_left);
  304. tmp->_right = _Copy(Root->_right);
  305. }
  306. return tmp;
  307. }
  308. Node* _Destory(Node* Root)
  309. {
  310. if (Root != NULL)
  311. {
  312. Root->_left = _Destory(Root->_left);
  313. Root->_right = _Destory(Root->_right);
  314. delete Root;
  315. Root = NULL;
  316. }
  317. return Root;
  318. }
  319. bool _Isbalance(Node* Root)//时间复杂度为n^2
  320. {
  321. if (Root == NULL)
  322. {
  323. return true;
  324. }
  325. int LeftHeight = _Height(Root->_left)+1;
  326. int RightHeight = _Height(Root->_right)+1;
  327. int sub = abs(RightHeight - LeftHeight);
  328. return ((sub < 2) && (_Isbalance(Root->_left)) && (_Isbalance(Root->_right)));
  329. }
  330. bool _IsbalanceOP(Node* Root, int& height)
  331. {
  332. if (Root == NULL)
  333. {
  334. height = 0;
  335. return true;
  336. }
  337. //记录左结点和右结点高度
  338. int LeftHeight = 0;
  339. int RightHeight = 0;
  340. if (_IsbalanceOP(Root->_left, LeftHeight) == false)
  341. {
  342. return false;
  343. }
  344. if (_IsbalanceOP(Root->_right, RightHeight) == false)
  345. {
  346. return false;
  347. }
  348. height = LeftHeight > RightHeight ? LeftHeight + 1 : RightHeight + 1;
  349. return abs(RightHeight - LeftHeight) < 2;
  350. }
  351. private:
  352. Node* _root;
  353. };
  354. void TestAVLTree()
  355. {
  356. //int a1[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
  357. int a1[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
  358. AVLTree<int>t;
  359. for (size_t i = 0; i < sizeof(a1) / sizeof(a1[0]); i++)
  360. {
  361. t.Insert(a1[i]);
  362. cout <<a1[i]<<" "<< t.Isbalance() << endl;
  363. }
  364. t.Inorder();
  365. cout << t.Isbalance() << endl;
  366. AVLTree<int>t1(t);
  367. t1.Inorder();
  368. }
  369. int main()
  370. {
  371. TestAVLTree();
  372. system("pause");
  373. return 0;
  374. }

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