Advertisement
StreetKatya

AVL/27.02/22:40

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