Advertisement
StreetKatya

AVL 14.04

Apr 14th, 2023
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.04 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7.  
  8. namespace AVLTree_03._03._23
  9. {
  10. public class AVLTree<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> where TKey : IComparable<TKey>
  11. {
  12. bool flagIfAddSecond;
  13. public int Count { get; private set; }
  14. private Node<TKey, TValue> _root; //корень
  15.  
  16. public AVLTree()
  17. {
  18. Count = 0;
  19. }
  20. //private int FindHightTheTree(Node<TKey, TValue> root)
  21. //{
  22. // if (root == null) { return 0; }
  23. // int hight = 0;
  24. // Queue<Node<TKey, TValue>> queue = new Queue<Node<TKey, TValue>>();
  25. // queue.Enqueue(root);
  26. // while (queue.Count > 0)
  27. // {
  28. // int countQue = queue.Count;
  29. // for (int i = countQue; i != 0; i--)
  30. // {
  31. // var current = queue.Dequeue();
  32. // if (current.Left != null)
  33. // {
  34. // queue.Enqueue(current.Left);
  35. // }
  36. // if (current.Right != null)
  37. // {
  38. // queue.Enqueue(current.Right);
  39. // }
  40. // }
  41. // hight++;
  42. // }
  43. // return hight;
  44. //}
  45. public void Add(TKey key, TValue value)
  46. {
  47. var node = new Node<TKey, TValue>(key, value);
  48. if (_root == null)
  49. {
  50. _root = node;
  51. Count++;
  52. return;
  53. }
  54. var current = _root;
  55. var parent = _root;
  56. while (current != null)
  57. {
  58. parent = current;
  59. if (current.Key.CompareTo(node.Key) == 0)
  60. {
  61. throw new ArgumentException("Such key is already added");
  62. }
  63. if (current.Key.CompareTo(node.Key) > 0)
  64. {
  65. current = current.Left;
  66. }
  67. else if (current.Key.CompareTo(node.Key) < 0)
  68. {
  69. current = current.Right;
  70. }
  71. }
  72. if (parent.Key.CompareTo(node.Key) > 0)
  73. {
  74. parent.Left = node;
  75. }
  76. if (parent.Key.CompareTo(node.Key) < 0)
  77. {
  78. parent.Right = node;
  79. }
  80. node.Parent = parent;
  81. Count++;
  82. Balancing(parent);
  83. }
  84.  
  85. public bool Delete(TKey key)
  86. {
  87. var node = FindElem(key);
  88. //Удаление
  89. if (node != null)
  90. {
  91. Node<TKey,TValue> BalancingNode = node.Parent;
  92. Count--;
  93. var nodeLeft = node.Left; var nodeRight = node.Right; var nodeParent = node.Parent;
  94. // если нет детей - узел удаляется
  95. if (nodeLeft == null && nodeRight == null)
  96. {
  97. if (nodeParent != null)//не корень
  98. {
  99. if (nodeParent.Left == node) nodeParent.Left = null;
  100. else nodeParent.Right = null;
  101. }
  102. else if(nodeParent == null)
  103. {
  104. _root = null;
  105. }
  106.  
  107. }
  108. else if(nodeLeft != null && nodeRight == null)//Один ребенок слева
  109. {
  110. if(nodeParent == null)//корень
  111. {
  112. nodeLeft.Parent = null;
  113. _root = nodeLeft;
  114. }
  115. else//не корень
  116. {
  117. nodeLeft.Parent = node.Parent;
  118. nodeLeft.Parent.Left = nodeLeft;
  119. }
  120. }
  121. else if(nodeLeft == null && nodeRight != null)//Один ребенок справа
  122. {
  123. if (nodeParent == null)//корень
  124. {
  125. nodeRight.Parent = null;
  126. _root = nodeRight;
  127. }
  128. else//не корень
  129. {
  130. nodeRight.Parent = node.Parent;
  131. nodeRight.Parent.Left = nodeRight;
  132. }
  133. }
  134. else if (nodeLeft != null && nodeRight != null)//Два ребенка
  135. {
  136. // ищем замену - самый левый из элементов правого поддерева
  137. var current = nodeRight;
  138. while (current.Left != null)
  139. {
  140. current = current.Left;
  141. }
  142. var minelement = current;
  143. BalancingNode = minelement.Parent;
  144. if (minelement.Right != null)//Работа с удалением minelement
  145. {
  146. minelement.Right.Parent = minelement.Parent;
  147. if (minelement.Parent == node)//Если минимальный элемент сразу справа от нода и у него есть ребёнок справа
  148. {
  149. minelement.Parent.Right = minelement.Right;
  150. }
  151. else minelement.Parent.Left = minelement.Right;
  152. }
  153. else
  154. {
  155. if(minelement.Parent.Right == minelement)
  156. {
  157. minelement.Parent.Right = null;
  158. }
  159. else
  160. {
  161. minelement.Parent.Left = null;
  162. }
  163. }
  164.  
  165. if(minelement.Parent == node)
  166. {
  167.  
  168. minelement.Parent = node.Parent;
  169. if(node.Parent.Left == node)
  170. {
  171. node.Parent.Left = minelement;
  172. }
  173. else node.Parent.Right = minelement;
  174. minelement.Left = node.Left;
  175. minelement.Right = node.Right;
  176. BalancingNode = minelement;
  177. }
  178. else
  179. {
  180. minelement.Left = nodeLeft; nodeLeft.Parent = minelement;
  181. minelement.Right = nodeRight; nodeRight.Parent = minelement;
  182. minelement.Parent = node.Parent;
  183. if (nodeParent == null)//корень
  184. {
  185. _root = minelement;
  186. _root.UpdateHeight();
  187. }
  188. }
  189.  
  190. }
  191. Balancing(BalancingNode);
  192. return true;
  193. }
  194. else
  195. {
  196. return false;
  197. //throw new ArgumentException("No such element in tree");
  198. }
  199. }
  200. public bool Contains(TKey key, TValue value)
  201. {
  202. // Поиск узла осуществляется другим методом.
  203. return FindElem(key) != null;
  204. }
  205. private void Balancing(Node<TKey, TValue> node)
  206. {
  207. while (node != null)
  208. {
  209. node.UpdateHeight();
  210. //int HightLeft = node.Left.Height; int HightRight = node.Right.Height;
  211. int nodeBF = node.BalanceFactor();
  212. if (Math.Abs(nodeBF) == 2)//тогда балансим
  213. {
  214. if(nodeBF < 0)//Левые повороты
  215. {
  216. if (node.Right.BalanceFactor() <= 0)//левый малый поворот
  217. {
  218. LeftSmallTurn(node);
  219. }
  220. else if (node.Right.BalanceFactor() > 0)//левый большой поворот
  221. {
  222. LeftBigTurn(node);
  223. }
  224. }
  225. else if(nodeBF > 0)//Правые повороты
  226. {
  227. if (node.Left.BalanceFactor() >= 0)//правый малый поворот
  228. {
  229. RightSmallTurn(node);
  230. }
  231. else if (node.Left.BalanceFactor() < 0)//правый большой поворот
  232. {
  233. RightBigTurn(node);
  234. }
  235. }
  236. }
  237. node = node.Parent;
  238. }
  239. }
  240. private void LeftSmallTurn(Node<TKey, TValue> node)
  241. {
  242. /*
  243. * A* B
  244. * / \ / \
  245. * L B --> A R
  246. * / \ / \
  247. * C R L C
  248. */
  249. var A = node;
  250. var B = node.Right;
  251. var C = B.Left;
  252.  
  253. A.Right = C;
  254. if(C != null) C.Parent = A;
  255. B.Left = A;
  256. B.Parent = A.Parent;
  257. if (A.Parent != null)//Если не корень, то привязываем родителя к получившейся верхушке
  258. {
  259. if (A.Parent.Left == A)//Если А слева от своего родителя
  260. {
  261. A.Parent.Left = B;
  262. }
  263. else //Если А справа от своего родителя
  264. {
  265. A.Parent.Right = B;
  266. }
  267. A.Parent = B;
  268. }
  269. else _root = B;
  270. A.UpdateHeight();
  271. B.UpdateHeight();
  272. }
  273. private void RightSmallTurn(Node<TKey, TValue> node)
  274. {
  275. /*
  276. * | |
  277. * A* B
  278. * / \ / \
  279. * B R --> L A
  280. * / \ / \
  281. * L C C R
  282. */
  283. var A = node;
  284. var B = A.Left;
  285. var C = B.Right;
  286. var L = B.Left;
  287. var R = A.Right;
  288.  
  289. B.Right = A;
  290. A.Left = C;
  291. if(C != null) C.Parent = A;
  292. B.Parent = A.Parent;
  293. if (A.Parent != null)//Если не корень, то привязываем родителя к получившейся верхушке
  294. {
  295. if (A.Parent.Left == A)//Если А слева от своего родителя
  296. {
  297. A.Parent.Left = B;
  298. }
  299. else //Если А справа от своего родителя
  300. {
  301. A.Parent.Right = B;
  302. }
  303. A.Parent = B;
  304. }
  305. else _root = B;
  306. A.UpdateHeight();
  307. B.UpdateHeight();
  308. }
  309. private void LeftBigTurn(Node<TKey, TValue> node)
  310. {
  311. /*
  312. * A A C
  313. * / \ / \ / \
  314. * L B L С A B
  315. * / \ --> / \ --> / \ / \
  316. * C R M B L M N R
  317. * / \ / \
  318. * M N N R
  319. */
  320. var A = node;
  321. var B = node.Right;
  322. var C = B.Left;
  323. //var L = A.Left;
  324. //var M = C.Left;
  325. var N = C.Right;
  326. //var R = B.Right;
  327.  
  328. B.Left = N;
  329. if (N != null)
  330. {
  331. N.Parent = B;
  332. }
  333. C.Right = B;
  334. B.Parent = C;
  335. A.Right = C;
  336. C.Parent = A;
  337. A.UpdateHeight();
  338. B.UpdateHeight();
  339. C.UpdateHeight();
  340. LeftSmallTurn(A);
  341. }
  342. private void RightBigTurn(Node<TKey, TValue> node)
  343. {
  344. /*
  345. * A A C
  346. * / \ / \ / \
  347. * B R C R B A
  348. * / \ --> / \ --> / \ / \
  349. * L C B N L M N R
  350. * / \ / \
  351. * M N L M
  352. */
  353. var A = node;
  354. var B = node.Left;
  355. var C = B.Right;
  356. //var L = B.Left;
  357. var M = C.Left;
  358. //var N = C.Right;
  359. //var R = A.Right;
  360.  
  361. B.Right = M;
  362. if (M != null)
  363. {
  364. M.Parent = B;
  365. }
  366. C.Left = B;
  367. B.Parent = C;
  368. A.Left = C;
  369. C.Parent = A;
  370. A.UpdateHeight();
  371. B.UpdateHeight();
  372. C.UpdateHeight();
  373. RightSmallTurn(A);
  374. }
  375. private Node<TKey, TValue> FindElem(TKey findKey)
  376. {
  377. // Попробуем найти значение в дереве.
  378. var current = _root;
  379.  
  380. // До тех пор, пока не нашли...
  381. while (current != null)
  382. {
  383. int result = current.Key.CompareTo(findKey);
  384.  
  385. if (result > 0)
  386. {
  387. // Если искомое значение меньше, идем налево.
  388. current = current.Left;
  389. }
  390. else if (result < 0)
  391. {
  392. // Если искомое значение больше, идем направо.
  393. current = current.Right;
  394. }
  395. else
  396. {
  397. // Если равны, то останавливаемся
  398. break;
  399. }
  400. }
  401.  
  402. return current;
  403. }
  404. private Node<TKey, TValue> FindMinElemOnTheRigthPath(Node<TKey, TValue> start)
  405. {
  406. while (start.Left != null)
  407. {
  408. start = start.Left;
  409. }
  410. return start;
  411. }
  412. IEnumerable<KeyValuePair<TKey, TValue>> Traverse(Node<TKey, TValue> node)
  413. {
  414. var nodes = new List<KeyValuePair<TKey,
  415. TValue>>();
  416. if (node != null)
  417. {
  418. nodes.AddRange(Traverse(node.Left));
  419. nodes.Add(new KeyValuePair<TKey, TValue>(node.Key, node.Value));
  420. nodes.AddRange(Traverse(node.Right));
  421. }
  422. return nodes;
  423. }
  424. public IEnumerable<KeyValuePair<TKey, TValue>> Traverse()
  425. {
  426. return Traverse(_root);
  427. }
  428. IEnumerator IEnumerable.GetEnumerator()
  429. {
  430. return Traverse().GetEnumerator();
  431. }
  432. public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
  433. {
  434. return Traverse().GetEnumerator();
  435. }
  436.  
  437. }
  438.  
  439. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement