Advertisement
SmnVadik

Lab5.2(Delphi)

Aug 19th, 2023
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 21.80 KB | None | 0 0
  1. unit MainUnit;
  2.  
  3. interface
  4.  
  5. uses
  6.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7.     System.Classes, Vcl.Graphics,
  8.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.StdCtrls;
  9.  
  10. type
  11.     TMainForm = class(TForm)
  12.         HeadLabel: TLabel;
  13.         Create: TButton;
  14.         AddElem: TButton;
  15.         Delete: TButton;
  16.         Show: TButton;
  17.         MainMenu1: TMainMenu;
  18.         PopupMenu1: TPopupMenu;
  19.         N1: TMenuItem;
  20.         N2: TMenuItem;
  21.         N3: TMenuItem;
  22.         N4: TMenuItem;
  23.         N5: TMenuItem;
  24.         OpenDialog1: TOpenDialog;
  25.         SaveDialog1: TSaveDialog;
  26.         N6: TMenuItem;
  27.         procedure N3Click(Sender: TObject);
  28.         procedure N2Click(Sender: TObject);
  29.         procedure AddElemClick(Sender: TObject);
  30.         procedure ShowClick(Sender: TObject);
  31.         procedure CreateClick(Sender: TObject);
  32.         procedure N4Click(Sender: TObject);
  33.         procedure N5Click(Sender: TObject);
  34.         procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  35.         procedure FormActivate(Sender: TObject);
  36.         procedure DeleteClick(Sender: TObject);
  37.         procedure N6Click(Sender: TObject);
  38.     private
  39.         { Private declarations }
  40.     public
  41.         { Public declarations }
  42.     end;
  43.  
  44. Type
  45.     TArray = Array Of Integer;
  46.     PNode = ^TTree;
  47.  
  48.     TTree = Record
  49.         Key: Integer;
  50.         Left, Right: PNode;
  51.     End;
  52.  
  53. var
  54.     MainForm: TMainForm;
  55.     Head, NodeForDeleting: PNode;
  56.     Path, SaveResult, StrWithNum: String;
  57.     IsFileOpen, WasTreeInitialized, ShowNumbers: Boolean;
  58.     Keys: TArray;
  59.  
  60. implementation
  61.  
  62. uses Add, Show;
  63.  
  64. {$R *.dfm}
  65.  
  66. procedure TMainForm.AddElemClick(Sender: TObject);
  67. begin
  68.     AddNode.ShowModal;
  69. end;
  70.  
  71. procedure DeleteTree(var Head: PNode);
  72. begin
  73.     if Head <> nil then
  74.     begin
  75.         DeleteTree(Head.Left);
  76.         DeleteTree(Head.Right);
  77.         Dispose(Head);
  78.         Head := nil;
  79.     end;
  80.     SetLength(Keys, 0);
  81. end;
  82.  
  83. procedure InitializeTree();
  84. Begin
  85.     WasTreeInitialized := True;
  86.     Head := nil;
  87.     SetLength(Keys, 0);
  88. End;
  89.  
  90. procedure TMainForm.CreateClick(Sender: TObject);
  91. begin
  92.     DeleteTree(Head);
  93.     InitializeTree();
  94.     Application.MessageBox('Пустое дерево создано!', 'Информация', 0);
  95. end;
  96.  
  97. procedure DeleteNode(var Root: PNode; Key: Integer);
  98. var
  99.     Current, Parent, Temp: PNode;
  100.     IsLeftChild: Boolean;
  101. begin
  102.     Current := Root;
  103.     Parent := nil;
  104.     IsLeftChild := False;
  105.  
  106.     while (Current <> nil) and (Current^.Key <> Key) do
  107.     begin
  108.         Parent := Current;
  109.         if Key < Current^.Key then
  110.         begin
  111.             Current := Current^.Left;
  112.             IsLeftChild := True;
  113.         end
  114.         else
  115.         begin
  116.             Current := Current^.Right;
  117.             IsLeftChild := False;
  118.         end;
  119.     end;
  120.  
  121.     if (Current^.Left = nil) and (Current^.Right = nil) then
  122.     begin
  123.         if Current = Root then
  124.             Root := nil
  125.         else if IsLeftChild then
  126.             Parent^.Left := nil
  127.         else
  128.             Parent^.Right := nil;
  129.         Dispose(Current);
  130.         Application.MessageBox('Элемент удален!', 'Информация', 0);
  131.     end
  132.  
  133.     else if Current^.Right = nil then
  134.     begin
  135.         if Current = Root then
  136.             Root := Current^.Left
  137.         else if IsLeftChild then
  138.             Parent^.Left := Current^.Left
  139.         else
  140.             Parent^.Right := Current^.Left;
  141.         Dispose(Current);
  142.         Application.MessageBox('Элемент удален!', 'Информация', 0);
  143.     end
  144.     else if Current^.Left = nil then
  145.     begin
  146.         if Current = Root then
  147.             Root := Current^.Right
  148.         else if IsLeftChild then
  149.             Parent^.Left := Current^.Right
  150.         else
  151.             Parent^.Right := Current^.Right;
  152.         Dispose(Current);
  153.         Application.MessageBox('Элемент удален!', 'Информация', 0);
  154.     end
  155.  
  156.     else
  157.     begin
  158.         Temp := Current^.Right;
  159.         Parent := Current;
  160.         while Temp^.Left <> nil do
  161.         begin
  162.             Parent := Temp;
  163.             Temp := Temp^.Left;
  164.         end;
  165.         Current^.Key := Temp^.Key;
  166.         if Parent^.Left = Temp then
  167.             Parent^.Left := Temp^.Right
  168.         else
  169.             Parent^.Right := Temp^.Right;
  170.         Dispose(Temp);
  171.         Application.MessageBox('Элемент удален!', 'Информация', 0);
  172.     end;
  173. end;
  174.  
  175. function CheckUserChoise(Num: Integer): Boolean;
  176. Var
  177.     IsInvalid: Boolean;
  178.     I: Integer;
  179. Begin
  180.     IsInvalid := True;
  181.     For I := Low(Keys) To High(Keys) Do
  182.         If Num = Keys[I] then
  183.         begin
  184.             IsInvalid := False;
  185.             Break;
  186.         end;
  187.     CheckUserChoise := IsInvalid;
  188. End;
  189.  
  190. procedure TMainForm.DeleteClick(Sender: TObject);
  191. var
  192.     NumForDeleting: Integer;
  193.     IsCorrect: Boolean;
  194. begin
  195.     If (WasTreeInitialized) and (Head <> nil) then
  196.     Begin
  197.         IsCorrect := True;
  198.         ShowNumbers := True;
  199.         ShowTree.ShowModal;
  200.         with AddNode Do
  201.         Begin
  202.             Caption := 'Удаление элемента';
  203.             Meeting.Caption := 'Введите элемент:';
  204.             N1.Enabled := False;
  205.             ShowModal;
  206.         End;
  207.         try
  208.             NumForDeleting := StrToInt(StrWithNum);
  209.         except
  210.             AddNode.Data.Text := '';
  211.             IsCorrect := False;
  212.             Application.MessageBox
  213.               ('В этом окне следует вводить удаляемый элемент.', 'Ошибка',
  214.               MB_ICONSTOP);
  215.         end;
  216.         If CheckUserChoise(NumForDeleting) and (IsCorrect) then
  217.         begin
  218.             AddNode.Data.Text := '';
  219.             IsCorrect := False;
  220.             Application.MessageBox
  221.               ('В этом окне следует вводить удаляемый элемент.', 'Ошибка',
  222.               MB_ICONSTOP);
  223.         end;
  224.         If IsCorrect then
  225.         begin
  226.             DeleteNode(Head, NumForDeleting);
  227.         end;
  228.     End
  229.     else if Not(WasTreeInitialized) then
  230.     begin
  231.         Application.MessageBox('Дерева не существует. Создайте его!',
  232.           'Информация', 0);
  233.     end
  234.     else
  235.     begin
  236.         Application.MessageBox
  237.           ('Дерево пустое. Добавьте в него элементы, чтобы было что удалять.',
  238.           'Информация', 0);
  239.     end;
  240. end;
  241.  
  242. procedure TMainForm.FormActivate(Sender: TObject);
  243. begin
  244.     WasTreeInitialized := False;
  245.     SetLength(Keys, 0);
  246. end;
  247.  
  248. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  249. begin
  250.     CanClose := Application.MessageBox('Вы действительно хотите выйти?',
  251.       'Выход', MB_YESNO + MB_ICONQUESTION) = ID_YES;
  252. end;
  253.  
  254. procedure TMainForm.N2Click(Sender: TObject);
  255. Const
  256.     INFO = 'Дерево — одна из наиболее широко распространённых структур данных в информатике, эмулирующая древовидную структуру в виде набора связанных узлов. Является связным графом, не содержащим циклы.';
  257.     INFO2 = #13#10 + #13#10 +
  258.       'Текстовый файл должен представлять из себя 1 строчку с числами, введенными через пробел. Информация из файла будет дополнять существующую.';
  259.  
  260. begin
  261.     Application.MessageBox(INFO + INFO2, 'Инструкция', 0);
  262. end;
  263.  
  264. procedure TMainForm.N3Click(Sender: TObject);
  265. begin
  266.     Application.MessageBox('Сымоник Вадим гр. 251004', 'Разработчик', 0);
  267. end;
  268.  
  269. procedure TMainForm.ShowClick(Sender: TObject);
  270. begin
  271.     If (WasTreeInitialized) and (Head <> nil) then
  272.     Begin
  273.         ShowTree.ShowModal;
  274.     End
  275.     else if Not(WasTreeInitialized) then
  276.     begin
  277.         Application.MessageBox('Дерева не существует. Создайте его!',
  278.           'Информация', 0);
  279.     end
  280.     else
  281.     begin
  282.         Application.MessageBox
  283.           ('Дерево пустое. Добавьте в него элементы, чтобы оно отобразилось.',
  284.           'Информация', 0);
  285.     end;
  286. end;
  287.  
  288. Function Open(): String;
  289. Begin
  290.     With MainForm Do
  291.     Begin
  292.         If OpenDialog1.Execute Then
  293.         Begin
  294.             Path := OpenDialog1.FileName;
  295.             IsFileOpen := True;
  296.         End
  297.         Else
  298.             IsFileOpen := False;
  299.     End;
  300.     Open := Path;
  301. End;
  302.  
  303. Function Save(): String;
  304. Begin
  305.     With MainForm Do
  306.     Begin
  307.         If SaveDialog1.Execute Then
  308.         Begin
  309.             Path := SaveDialog1.FileName;
  310.             IsFileOpen := True;
  311.         End
  312.         Else
  313.             IsFileOpen := False;
  314.     End;
  315.     Save := Path;
  316. End;
  317.  
  318. Function GetString(Var FileOutput: TextFile): String; Stdcall;
  319.   External 'My1stLib.dll';
  320.  
  321. type
  322.     TStr = Array of String;
  323.  
  324. function SeparateString(Str: String): TStr; Stdcall; External 'My1stLib.dll';
  325.  
  326. Function CreateNewNode(Data: Integer; Node: PNode): PNode;
  327. Begin
  328.     New(Result);
  329.     Result.Key := Data;
  330.     Result.Right := Nil;
  331.     Result.Left := Nil;
  332. End;
  333.  
  334. Procedure InsertNode(Node: PNode; Data: Integer);
  335. Begin
  336.     If (Data < Node.Key) Then
  337.     Begin
  338.         If (Node.Left <> Nil) Then
  339.             InsertNode(Node.Left, Data)
  340.         Else
  341.             Node.Left := CreateNewNode(Data, Node);
  342.     End
  343.     Else
  344.     Begin
  345.         If (Node.Right <> Nil) Then
  346.             InsertNode(Node.Right, Data)
  347.         Else
  348.             Node.Right := CreateNewNode(Data, Node);
  349.     End;
  350. End;
  351.  
  352. Procedure AddNodeInTree(Data: Integer);
  353. Var
  354.     Node: PNode;
  355. Begin
  356.     SetLength(Keys, (Length(Keys) + 1));
  357.     Keys[High(Keys)] := Data;
  358.     If (Head <> Nil) Then
  359.         InsertNode(Head, Data)
  360.     Else
  361.         Head := CreateNewNode(Data, Nil);
  362. End;
  363.  
  364. function CheckRepetitions(Num: Integer): Boolean;
  365. Var
  366.     IsCorrect: Boolean;
  367.     I: Integer;
  368. Begin
  369.     IsCorrect := True;
  370.     For I := Low(Keys) To High(Keys) Do
  371.         If Num = Keys[I] then
  372.         begin
  373.             IsCorrect := False;
  374.             Break;
  375.         end;
  376.     CheckRepetitions := IsCorrect;
  377. End;
  378.  
  379. function CheckFile(Arr: TStr): Boolean;
  380. Var
  381.     IsCorrect: Boolean;
  382.     I, J: Integer;
  383. Begin
  384.     IsCorrect := True;
  385.     For I := Low(Keys) To High(Keys) Do
  386.         For J := I + 1 To High(Keys) Do
  387.             If Arr[I] = Arr[J] then
  388.             begin
  389.                 IsCorrect := False;
  390.                 Break
  391.             end;
  392.     I := 0;
  393.     While ((I <= High(Keys)) and (IsCorrect)) Do
  394.     begin
  395.         IsCorrect := CheckRepetitions(StrToInt(Arr[I]));
  396.         Inc(I);
  397.     end;
  398.     CheckFile := IsCorrect;
  399. End;
  400.  
  401. procedure TMainForm.N4Click(Sender: TObject);
  402. Var
  403.     FileInput: TextFile;
  404.     StrWithNodes: String;
  405.     Arr: TStr;
  406.     I: Integer;
  407.     NewNode, Node: PNode;
  408.     WillContinue: Boolean;
  409. begin
  410.     IsFileOpen := False;
  411.     Path := Open();
  412.     AssignFile(FileInput, Path);
  413.     If ExtractFileExt(Path) <> '.txt' then
  414.         raise Exception.Create
  415.           ('Файл должен быть текстовым. Проверьте исходные данные.');
  416.     Reset(FileInput);
  417.     If (IsFileOpen) then
  418.         StrWithNodes := GetString(FileInput);
  419.     CloseFile(FileInput);
  420.     If (StrWithNodes <> '') then
  421.     Begin
  422.         Arr := SeparateString(StrWithNodes);
  423.         WillContinue := True;
  424.         For I := 0 To High(Arr) Do
  425.             If (Arr[I].Length > 3) then
  426.             begin
  427.                 WillContinue := False;
  428.                 raise Exception.Create
  429.                   ('Длина одного элемента не должна превышать 3 символов. Проверьте исходные данные.');
  430.             end;
  431.         If WillContinue then
  432.         Begin
  433.             If CheckFile(Arr) then
  434.             Begin
  435.                 For I := Low(Arr) to High(Arr) Do
  436.                 begin
  437.                     If Arr[I] <> '' then
  438.                         AddNodeInTree(StrToInt(Arr[I]));
  439.                 end;
  440.                 WasTreeInitialized := True;
  441.                 Application.MessageBox('Готово!', 'Информация', 0);
  442.             End
  443.             else
  444.             begin
  445.                 Application.MessageBox
  446.                   ('В файле есть повторяющиеся элементы или в файле есть уже существующие элементы.',
  447.                   'Ошибка', MB_ICONSTOP);
  448.             end;
  449.         End;
  450.     End;
  451. end;
  452.  
  453. procedure CreateStringToSave(var Head: PNode);
  454. begin
  455.     if Head <> nil then
  456.     begin
  457.         CreateStringToSave(Head.Left);
  458.         CreateStringToSave(Head.Right);
  459.         SaveResult := SaveResult + IntToStr(Head.Key) + ' ';
  460.     end;
  461. end;
  462.  
  463. procedure TMainForm.N5Click(Sender: TObject);
  464. Var
  465.     FileOutput: TextFile;
  466.     IsCorrect: Boolean;
  467.     CurrNode: PNode;
  468. begin
  469.     If Head = nil then
  470.     begin
  471.         Application.MessageBox('Дерево пустое.', 'Информация', 0);
  472.         Exit
  473.     end;
  474.     SaveResult := '';
  475.     IsCorrect := True;
  476.     Path := Save();
  477.     If (IsFileOpen) Then
  478.     Begin
  479.         CreateStringToSave(Head);
  480.         try
  481.             AssignFile(FileOutput, Path);
  482.             Rewrite(FileOutput);
  483.             Write(FileOutput, SaveResult);
  484.             CloseFile(FileOutput);
  485.         except
  486.             IsCorrect := False;
  487.             Application.MessageBox('Запись в файл не удалась.', 'Ошибка',
  488.               MB_ICONSTOP);
  489.         end;
  490.  
  491.         If IsCorrect then
  492.         Begin
  493.             Application.MessageBox('Запись файла выполнена успешно.',
  494.               'Результат', 0);
  495.         End;
  496.     End;
  497. end;
  498.  
  499. procedure TMainForm.N6Click(Sender: TObject);
  500. begin
  501.     Application.MessageBox
  502.       ('Вывести номера вершин, для которых высота левого поддерева не равна высоте  правого поддерева.',
  503.       'Задание', 0);
  504. end;
  505.  
  506. end.
  507.  
  508.  
  509.  
  510. unit Add;
  511.  
  512. interface
  513.  
  514. uses
  515.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  516.     System.Classes, Vcl.Graphics,
  517.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Menus, Vcl.ExtCtrls;
  518.  
  519. type
  520.     TAddNode = class(TForm)
  521.         Data: TEdit;
  522.         Meeting: TLabel;
  523.         MainMenu1: TMainMenu;
  524.         N1: TMenuItem;
  525.         procedure DataKeyPress(Sender: TObject; var Key: Char);
  526.         procedure FormKeyPress(Sender: TObject; var Key: Char);
  527.         procedure FormClose(Sender: TObject; var Action: TCloseAction);
  528.         procedure N1Click(Sender: TObject);
  529.         procedure FormDeactivate(Sender: TObject);
  530.     private
  531.         { Private declarations }
  532.     public
  533.         { Public declarations }
  534.     end;
  535.  
  536. var
  537.     AddNode: TAddNode;
  538.  
  539. implementation
  540.  
  541. {$R *.dfm}
  542.  
  543. Uses MainUnit;
  544.  
  545. Function CreateNewNode(Data: Integer; Node: PNode): PNode;
  546. Begin
  547.     New(Result);
  548.     Result.Key := Data;
  549.     Result.Right := Nil;
  550.     Result.Left := Nil;
  551. End;
  552.  
  553. Procedure InsertNode(Node: PNode; Data: Integer);
  554. Begin
  555.     If (Data < Node.Key) Then
  556.     Begin
  557.         If (Node.Left <> Nil) Then
  558.             InsertNode(Node.Left, Data)
  559.         Else
  560.             Node.Left := CreateNewNode(Data, Node);
  561.     End
  562.     Else
  563.     Begin
  564.         If (Node.Right <> Nil) Then
  565.             InsertNode(Node.Right, Data)
  566.         Else
  567.             Node.Right := CreateNewNode(Data, Node);
  568.     End;
  569. End;
  570.  
  571. Procedure AddNodeInTree(Data: Integer);
  572. Var
  573.     Node: PNode;
  574. Begin
  575.     SetLength(Keys, (Length(Keys) + 1));
  576.     Keys[High(Keys)] := Data;
  577.     If (Head <> Nil) Then
  578.         InsertNode(Head, Data)
  579.     Else
  580.         Head := CreateNewNode(Data, Nil);
  581. End;
  582.  
  583. function CheckContent(Str: String): Boolean;
  584. var
  585.     IsCorrect: Boolean;
  586.     NumberForTest: Integer;
  587. begin
  588.     IsCorrect := True;
  589.     Try
  590.         NumberForTest := StrToInt(Str);
  591.     Except
  592.         IsCorrect := False;
  593.  
  594.     End;
  595.     CheckContent := IsCorrect;
  596. end;
  597.  
  598. function CheckRepetitions(Num: Integer): Boolean;
  599. Var
  600.     IsCorrect: Boolean;
  601.     I: Integer;
  602. Begin
  603.     IsCorrect := True;
  604.     For I := Low(Keys) To High(Keys) Do
  605.         If Num = Keys[I] then
  606.         begin
  607.             IsCorrect := False;
  608.             Break;
  609.         end;
  610.     CheckRepetitions := IsCorrect;
  611. End;
  612.  
  613. procedure TAddNode.DataKeyPress(Sender: TObject; var Key: Char);
  614. var
  615.     IsOverFlow: Boolean;
  616. begin
  617.     If (Key = #13) and (Data.Text <> '') and (N1.Enabled) then
  618.     begin
  619.         If (CheckContent(Data.Text)) then
  620.         Begin
  621.             If CheckRepetitions(StrToInt(Data.Text)) then
  622.             begin
  623.                 AddNodeInTree(StrToInt(Data.Text));
  624.                 Application.MessageBox('Элемент добавлен!',
  625.                   'Предупреждение', 0);
  626.                 WasTreeInitialized := True;
  627.             end
  628.             else
  629.             begin
  630.                 Application.MessageBox
  631.                   ('К сожалению, нельзя добавлять повторяющиеся элементы. Повторите ввод.',
  632.                   'Ошибка', MB_ICONSTOP);
  633.             end;
  634.         End
  635.         else
  636.         begin
  637.             Application.MessageBox
  638.               ('Разрешено вводить только целочисленные значения.', 'Ошибка',
  639.               MB_ICONSTOP);
  640.         end;
  641.         Data.Text := '';
  642.     end;
  643.     If (Key = #13) and (Data.Text <> '') and Not(N1.Enabled) then
  644.     begin
  645.         StrWithNum := Data.Text;
  646.         Data.Text := '';
  647.         AddNode.Close;
  648.     end
  649. end;
  650.  
  651. procedure TAddNode.FormClose(Sender: TObject; var Action: TCloseAction);
  652. begin
  653.     AddNode.TabStop := True;
  654. end;
  655.  
  656. procedure TAddNode.FormDeactivate(Sender: TObject);
  657. begin
  658.     AddNode.Caption := 'Добавить';
  659.     AddNode.Meeting.Caption := 'Введите элемент:';
  660.     AddNode.N1.Enabled := True;
  661. end;
  662.  
  663. procedure TAddNode.FormKeyPress(Sender: TObject; var Key: Char);
  664. begin
  665.     Data.TabStop := True;
  666. end;
  667.  
  668. procedure TAddNode.N1Click(Sender: TObject);
  669. begin
  670.     Application.MessageBox
  671.       ('Узлами дерева являются целочисленные значения в диапазоне [-9..99]',
  672.       'Информация', 0);
  673. end;
  674.  
  675. end.
  676.  
  677.  
  678.  
  679. unit Show;
  680.  
  681. interface
  682.  
  683. uses
  684.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  685.     System.Classes, Vcl.Graphics,
  686.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ExtCtrls;
  687.  
  688. type
  689.     TShowTree = class(TForm)
  690.         TreeImage: TImage;
  691.         procedure FormActivate(Sender: TObject);
  692.         procedure FormDeactivate(Sender: TObject);
  693.     private
  694.         { Private declarations }
  695.     public
  696.         { Public declarations }
  697.     end;
  698.  
  699. var
  700.     ShowTree: TShowTree;
  701.     str: String;
  702.  
  703. implementation
  704.  
  705. {$R *.dfm}
  706.  
  707. uses MainUnit;
  708.  
  709. Function max(A: Integer; B: Integer): Integer;
  710. Begin
  711.     if A >= B Then
  712.         Result := A
  713.     Else
  714.         Result := B
  715. End;
  716.  
  717. Function FindHeight(const Head: PNode): Integer;
  718. var
  719.     Curr: PNode;
  720. begin
  721.     Curr := Head;
  722.  
  723.     if Curr = nil then
  724.     Begin
  725.         Result := 0;
  726.         Exit;
  727.     End;
  728.  
  729.     If ((Curr.Left <> nil) And (Curr.Left.Right = Curr) And (Curr.Right <> nil)
  730.       And (Curr.Right.Left = Curr)) Then
  731.     Begin
  732.         Result := 1;
  733.         Exit;
  734.     End;
  735.  
  736.     Result := 1 + max(FindHeight(Curr.Left), FindHeight(Curr.Right));
  737.  
  738. end;
  739.  
  740. procedure DrawBranch(X1, Y1, X2, Y2: Integer);
  741. Begin
  742.     ShowTree.TreeImage.Canvas.MoveTo(X1, Y1);
  743.     ShowTree.TreeImage.Canvas.LineTo(X2, Y2);
  744. End;
  745.  
  746. Procedure DrawTree(Head: PNode; X1, Y1, X2, Y2, Shift: Integer);
  747. Var
  748.     Tree: PNode;
  749.     Cord: Integer;
  750. Const
  751.     OffSetTextByX = 8;
  752.     OffSetTextByY = 10;
  753. Begin
  754.     Tree := Head;
  755.     With (ShowTree.TreeImage.Canvas) Do
  756.     Begin
  757.         Pen.Width := 3;
  758.         Font.Size := 12;
  759.         Ellipse(X1, Y1, X2, Y2);
  760.         TextOut(X1 + OffSetTextByX, Y1 + OffSetTextByY, IntToStr((Tree^.Key)));
  761.     End;
  762.     If (Tree <> Nil) Then
  763.     Begin
  764.         If (FindHeight(Tree.Left) <> FindHeight(Tree.Right)) Then
  765.         Begin
  766.             str := str + IntToStr(Tree^.Key) + ' ';
  767.         End;
  768.         If (Tree.Left <> Nil) Then
  769.         Begin
  770.             DrawBranch(X1, Y1 + 24, X1 - Shift, Y2 + 24);
  771.             DrawTree(Tree.Left, X1 - Shift, Y1 + 48, X2 - Shift, Y2 + 48,
  772.               (Shift Div 2));
  773.         End;
  774.         If (Tree.Right <> Nil) Then
  775.         Begin
  776.             DrawBranch(X2, Y1 + 24, X2 + Shift, Y2 + 24);
  777.             DrawTree(Tree.Right, X1 + Shift, Y2, X2 + Shift, Y2 + 48,
  778.               (Shift Div 2));
  779.         End;
  780.     End;
  781.  
  782. End;
  783.  
  784. procedure TShowTree.FormActivate(Sender: TObject);
  785. const
  786.     Shift = 120;
  787.     INFO1 = 'Выберите вершину, которую хотите удалить.';
  788.     INFO2 = 'Далее закройте окно и введите число с этой вершины';
  789.     INFO3 = 'в соответствующее поле.';
  790.     INFO4 = 'Вершины: ';
  791. begin
  792.     TreeImage.Picture := nil;
  793.     DrawTree(Head, ShowTree.TreeImage.Width Div 2, 8,
  794.       ShowTree.TreeImage.Width Div 2 + 48, 56, Shift);
  795.     ShowTree.TreeImage.Canvas.TextOut(0, 200, INFO4 + str);
  796.     If ShowNumbers then
  797.     begin
  798.         with ShowTree.TreeImage.Canvas Do
  799.         begin
  800.             Pen.Width := 2;
  801.             Font.Size := 8;
  802.             TextOut(0, 0, INFO1);
  803.             TextOut(0, 20, INFO2);
  804.             TextOut(0, 40, INFO3);
  805.         end;
  806.     end;
  807. end;
  808.  
  809. procedure TShowTree.FormDeactivate(Sender: TObject);
  810. begin
  811.     ShowNumbers := False;
  812.     str := '';
  813.  
  814. end;
  815.  
  816. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement