Advertisement
StreetKatya

WorkingButSlowAVL

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