deced

Untitled

Mar 29th, 2021 (edited)
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.22 KB | None | 0 0
  1. unit Tree;
  2.  
  3. Если ты это читаешь, то с меня мороженное)
  4.  
  5. interface
  6.  
  7. uses Node, SysUtils;
  8.  
  9. type
  10. TTree = class
  11. RootNode: TNode;
  12. procedure Add(Value: Integer); // объявляем процедуру добавления
  13. procedure Delete(Value: Integer); // объявляем процедуру удаления
  14. // объявляем рекурсивную функцию удаления
  15. function DeleteRecursive(Current: TNode; Value: Integer): TNode;
  16. // объявляем рекурсивную процедуру добавления
  17. procedure AddRecursive(Current: TNode; Value: Integer);
  18. // процедура для полной очистки дерева
  19. procedure Clear();
  20. // функция для получения наименьшего элемента в правом поддереве
  21. function GetSmallest(Root: TNode): Integer;
  22. end;
  23.  
  24. implementation
  25.  
  26. procedure TTree.Clear();
  27. begin
  28. // чтобы полностью очистить дерево достаточно присвоить корню nil
  29. RootNode := nil;
  30. end;
  31.  
  32.  
  33.  
  34.  
  35. // реализация процедур/функций дерева
  36. function TTree.GetSmallest(Root: TNode): Integer;
  37. begin
  38. if (Root.Left = nil) then
  39. // если нижняя левая нода равна nil, то возвращаем значение текущейноды
  40. Result := Root.Value
  41. else
  42. // иначе рекурсивно вызываем эту функцию для левой ноды
  43. Result := GetSmallest(Root.Left);
  44.  
  45. end;
  46.  
  47.  
  48. procedure TTree.Add(Value: Integer);
  49. begin
  50. // если корень равен nil, то присваиваем его новую ноду со значением Value
  51. if RootNode = nil then
  52. RootNode := TNode.Create(Value)
  53. else
  54. // иначе вызываем рекурсивную процедуру добавления
  55. AddRecursive(RootNode, Value)
  56. end;
  57.  
  58. procedure TTree.Delete(Value: Integer);
  59. begin
  60. // вызываем рерурсивную процедуру удаления
  61. RootNode := DeleteRecursive(RootNode, Value);
  62. end;
  63.  
  64. function TTree.DeleteRecursive(Current: TNode; Value: Integer): TNode;
  65. var
  66. Smallest: Integer;
  67. begin
  68.  
  69. // в переменной Value у нас значение, которое надо удалить
  70. // если оно равно значение текущей ноды, то удаляем текущую ноду
  71. if (Value = Current.Value) then
  72. begin
  73. if (Current.Left = nil) and (Current.Right = nil) then
  74. begin
  75. Current := nil;
  76. Result := Current;
  77. end
  78. else if ((Current.Right = nil) and (Current.Left <> nil)) then
  79. // если существует только левый потомок, то возвращаем его
  80. Result := Current.Left
  81.  
  82. else if ((Current.Left = nil) and (Current.Right <> nil)) then
  83. // если существует только правый, то вернём его
  84. Result := Current.Right
  85. else
  86. begin
  87. // если два прошлых ифа не сработали, то это значит, что у текущей ноды два потомка
  88. // по правилу удаления получаем минимальный элемент из правого поддерева
  89. Smallest := GetSmallest(Current.Right);
  90. // и присваиваем его текущей ноде
  91. Current.Value := Smallest;
  92. // после чего надо удалить тот минимальный элемент
  93. Current.Right := DeleteRecursive(Current.Right, Smallest);
  94. Result := Current;
  95. end;
  96. end
  97. else if (Value < Current.Value) then
  98. begin
  99. // если искомое значение меньше значения текущей ноды,
  100. // то будем смотреть левого потомка
  101. Current.Left := DeleteRecursive(Current.Left, Value);
  102. Result := Current;
  103. end
  104. else
  105. begin
  106. // остается только случай, когда искомое значение больше значения текущей ноды
  107. // в таком случае смотрим левого потомка
  108. Current.Right := DeleteRecursive(Current.Right, Value);
  109. Result := Current;
  110. end;
  111.  
  112. end;
  113.  
  114. procedure TTree.AddRecursive(Current: TNode; Value: Integer);
  115. begin
  116. // если значение, которое мы хотим добавить меньше значения текущей ноды
  117. // то идём в правое поддерево
  118. if (Current.Value < Value) then
  119. begin
  120.  
  121. if (Current.Right = nil) then
  122. // если правой ноды не существует, то создаем её и записываем туда значение,
  123. // которое хотели добавить
  124. Current.Right := TNode.Create(Value)
  125. else
  126. // правая нода существует, рекурсивно вызываем добавление, передавая туда правую ноду
  127. AddRecursive(Current.Right, Value);
  128. end
  129. // если значение, которое мы хотим добавить больше значения текущей ноды
  130. // то идём в левое поддерево
  131. else if (Current.Value > Value) then
  132. begin
  133. if (Current.Left = nil) then
  134. // если левой ноды не существует, то создаем её и записываем туда значение,
  135. // которое хотели добавить
  136. Current.Left := TNode.Create(Value)
  137. else
  138. // левая нода существует, рекурсивно вызываем добавление, передавая туда правую ноду
  139. AddRecursive(Current.Left, Value);
  140.  
  141. end;
  142.  
  143. end;
  144.  
  145. end.
Add Comment
Please, Sign In to add comment