Advertisement
THOMAS_SHELBY_18

5_2DELPHI не потерять бы блин

Mar 11th, 2024 (edited)
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 21.24 KB | Source Code | 0 0
  1. unit MainUnit;
  2.  
  3. interface
  4.  
  5. uses
  6.     Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.     Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Menus, Clipbrd,
  8.   Vcl.ExtDlgs;
  9.  
  10. type
  11.   TMainForm = class(TForm)
  12.     ValueEdit: TEdit;
  13.     AddButton: TButton;
  14.     ProcessingButton: TButton;
  15.     DeleteButton: TButton;
  16.     ExitButton: TButton;
  17.     TreeImage: TImage;
  18.     MainMenu: TMainMenu;
  19.     FileMenuItem: TMenuItem;
  20.     OpenMenuItem: TMenuItem;
  21.     SaveMenuItem: TMenuItem;
  22.     ManualMenuItem: TMenuItem;
  23.     AboutDeveloperMenuItem: TMenuItem;
  24.     OpenDialog: TOpenDialog;
  25.     CopyPastePopupMenu: TPopupMenu;
  26.     CopyButton: TMenuItem;
  27.     PasteButton: TMenuItem;
  28.     CutButton: TMenuItem;
  29.     ConditionLabel: TLabel;
  30.     ScrollBox: TScrollBox;
  31.     AnswerLabel: TLabel;
  32.     SavePictureDialog: TSavePictureDialog;
  33.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  34.     procedure ExitButtonClick(Sender: TObject);
  35.     procedure ManualMenuItemClick(Sender: TObject);
  36.     procedure AboutDeveloperMenuItemClick(Sender: TObject);
  37.     procedure CopyButtonClick(Sender: TObject);
  38.     procedure PasteButtonClick(Sender: TObject);
  39.     procedure CutButtonClick(Sender: TObject);
  40.     procedure CopyPastePopupMenuPopup(Sender: TObject);
  41.     procedure ValueEditChange(Sender: TObject);
  42.     procedure ValueEditKeyDown(Sender: TObject; var Key: Word;
  43.       Shift: TShiftState);
  44.     procedure ValueEditDblClick(Sender: TObject);
  45.     procedure ValueEditKeyPress(Sender: TObject; var Key: Char);
  46.     procedure FormCreate(Sender: TObject);
  47.     procedure AddButtonClick(Sender: TObject);
  48.     procedure DeleteButtonClick(Sender: TObject);
  49.     procedure ProcessingButtonClick(Sender: TObject);
  50.     procedure OpenMenuItemClick(Sender: TObject);
  51.     procedure SaveMenuItemClick(Sender: TObject);
  52.   private
  53.     { Private declarations }
  54.   public
  55.     { Public declarations }
  56.   end;
  57.  
  58. var
  59.   MainForm: TMainForm;
  60.  
  61. implementation
  62. uses
  63.     BinaryTreeUnit;
  64.  
  65. const
  66.     kBACKSPACE = #8;
  67.     kINSERT = 45;
  68.     MIN_VALUE = 1;
  69.     MAX_VALUE = 9999;
  70.     RADIUS = 20;
  71.     DELTA_X = 30;
  72.     DELTA_Y = 35;
  73.     DEFAULT_HEIGHT = 550;
  74.     DEFAULT_WIDTH = 700  ;
  75.  
  76. var
  77.     TreeStart: TPointer;
  78.     MinTreeCoord, MaxTreeCoord: Integer;
  79.  
  80. {$R *.dfm}
  81.  
  82. procedure TMainForm.AboutDeveloperMenuItemClick(Sender: TObject);
  83. begin
  84.     MessageBox(Handle, 'Разработчик: Наривончик Александр Михайлович, гр. 351004', 'О разработчике', MB_OK Or MB_ICONINFORMATION);
  85. end;
  86.  
  87. procedure TMainForm.CopyButtonClick(Sender: TObject);
  88. begin
  89.     ValueEdit.CopyToClipboard;
  90. end;
  91.  
  92. procedure TMainForm.CopyPastePopupMenuPopup(Sender: TObject);
  93. var
  94.     IValue: Integer;
  95.     Buffer: String;
  96.     IsCorrect: Boolean;
  97. begin
  98.     Buffer := Clipboard.AsText;
  99.     IsCorrect := TryStrToInt(Buffer, IValue);
  100.     PasteButton.Enabled := IsCorrect;
  101. end;
  102.  
  103. procedure TMainForm.CutButtonClick(Sender: TObject);
  104. begin
  105.     ValueEdit.CutToClipboard;
  106. end;
  107.  
  108. procedure TMainForm.PasteButtonClick(Sender: TObject);
  109. begin
  110.     ValueEdit.PasteFromClipboard;
  111. end;
  112.  
  113. procedure EditButtonEnabled();
  114. begin
  115.     with MainForm do
  116.     begin
  117.         AddButton.Enabled := ValueEdit.Text <> '';
  118.         DeleteButton.Enabled := ValueEdit.Text <> '';
  119.     end;
  120. end;
  121.  
  122. procedure TMainForm.ValueEditChange(Sender: TObject);
  123. var
  124.     CursPos: Byte;
  125.     TempStr: String;
  126.     IValue: Integer;
  127. begin
  128.     with ValueEdit do
  129.     begin
  130.         if Text = '0' then
  131.             Text := ''
  132.         else
  133.             if (Length(Text) > 0) then
  134.             begin
  135.                 CursPos := SelStart;
  136.                 TempStr := Text;
  137.  
  138.                 if not TryStrToInt(TempStr, IValue) then
  139.                 begin
  140.                     Delete (TempStr, SelStart, 1);
  141.                     Text := TempStr;
  142.                     SelStart := CursPos-1;
  143.                 end
  144.                 else
  145.                 begin
  146.                     Text := IntToStr(IValue);
  147.                     SelStart := CursPos;
  148.                 end;
  149.             end;
  150.     end;
  151.     EditButtonEnabled;
  152.     AnswerLabel.Caption := ''
  153. end;
  154.  
  155. procedure TMainForm.ValueEditDblClick(Sender: TObject);
  156. begin
  157.     ValueEdit.Text := '';
  158. end;
  159.  
  160. procedure TMainForm.ValueEditKeyDown(Sender: TObject; var Key: Word;
  161.   Shift: TShiftState);
  162. begin
  163.     if Key = kINSERT then
  164.         Key := 0;
  165. end;
  166.  
  167. procedure TMainForm.ValueEditKeyPress(Sender: TObject; var Key: Char);
  168. begin
  169.     if Not (Key in ['0'..'9', kBACKSPACE]) then
  170.         Key := #0;
  171. end;
  172.  
  173. procedure TMainForm.ExitButtonClick(Sender: TObject);
  174. begin
  175.     MainForm.Close;
  176. end;
  177.  
  178. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  179. begin
  180.     CanClose := MessageBox(Handle, 'Вы действительно хотите выйти?', 'Вы уверены?', MB_YESNO Or MB_ICONQUESTION) = IDYES;
  181. end;
  182.  
  183. procedure TMainForm.FormCreate(Sender: TObject);
  184. begin
  185.     TreeStart := CreateEmptyTree;
  186.     TreeImage.Width := DEFAULT_WIDTH;
  187.     TreeImage.Height := DEFAULT_HEIGHT;
  188. end;
  189.  
  190. procedure TMainForm.ManualMenuItemClick(Sender: TObject);
  191. begin
  192.     MessageBox(Handle, '1. Введите значение (от 1 до 9999) нового узла в поле и нажмите кнопку "Добавить". Постройте таким образом бинарное дерево' + #13#10 + '2. Чтобы удалить узел, введите его значение в поле и нажмите удалить.' + #13#10 + '3. Нажмите кнопку "Обработать" и получите результат!'+ #13#10 + '4. В случае ввода из файла убедитесь, что файл содержит значение каждого узла в новой строке.', 'Инструкция', MB_OK Or MB_ICONINFORMATION);
  193. end;
  194.  
  195. procedure DrawTree(TreeRoot: TPointer; X, Y: Integer);
  196. var
  197.     Coef: Integer;
  198. begin
  199.     with MainForm.TreeImage do
  200.     begin
  201.         Canvas.Ellipse(X-RADIUS, Y-RADIUS, X+RADIUS, Y+RADIUS);
  202.         Canvas.TextOut(X-7, Y-7, IntToStr(TreeRoot^.Value));
  203.  
  204.         if (TreeRoot^.NextLeft <> nil) and (TreeRoot^.NextRight = nil) then
  205.         begin
  206.             DrawTree(TreeRoot^.NextLeft, X - DELTA_X, Y+DELTA_Y);
  207.             Canvas.MoveTo(X - RADIUS, Y);
  208.             Canvas.LineTo(X - DELTA_X, Y+DELTA_Y-RADIUS);
  209.         end
  210.         else if (TreeRoot^.NextRight <> nil) and (TreeRoot^.NextLeft = nil) then
  211.         begin
  212.             DrawTree(TreeRoot^.NextRight, X + DELTA_X, Y+DELTA_Y);
  213.             Canvas.MoveTo(X + RADIUS, Y);
  214.             Canvas.LineTo(X + DELTA_X, Y+DELTA_Y-RADIUS);
  215.         end
  216.         else if (TreeRoot^.NextRight <> nil) and (TreeRoot^.NextLeft <> nil) then
  217.         begin
  218.             Coef := CalculateTreeCoef(TreeRoot^.NextLeft);
  219.             DrawTree(TreeRoot^.NextLeft, X - Coef * DELTA_X, Y+DELTA_Y);
  220.             Canvas.MoveTo(X-RADIUS, Y);
  221.             Canvas.LineTo(X - Coef * DELTA_X, Y+DELTA_Y-RADIUS);
  222.  
  223.             Coef := CalculateTreeCoef(TreeRoot^.NextRight);
  224.             DrawTree(TreeRoot^.NextRight, X + Coef * DELTA_X, Y+DELTA_Y);
  225.             Canvas.MoveTo(X+RADIUS, Y);
  226.             Canvas.LineTo(X + Coef * DELTA_X, Y+DELTA_Y-RADIUS);
  227.         end;
  228.     end;
  229. end;
  230.  
  231. procedure CalculateWidth(TreeRoot: TPointer; X, Y: Integer);
  232. var
  233.     Coef: Integer;
  234. begin
  235.     if TreeRoot <> nil then
  236.     begin
  237.         if (TreeRoot^.NextLeft <> nil) and (TreeRoot^.NextRight = nil) then
  238.         begin
  239.             CalculateWidth(TreeRoot^.NextLeft, X - DELTA_X, Y+DELTA_Y);
  240.         end
  241.         else if (TreeRoot^.NextRight <> nil) and (TreeRoot^.NextLeft = nil) then
  242.         begin
  243.             CalculateWidth(TreeRoot^.NextRight, X + DELTA_X, Y+DELTA_Y);
  244.         end
  245.         else if (TreeRoot^.NextRight <> nil) and (TreeRoot^.NextLeft <> nil) then
  246.         begin
  247.             Coef := CalculateTreeCoef(TreeRoot^.NextLeft);
  248.             CalculateWidth(TreeRoot^.NextLeft, X - Coef * DELTA_X, Y+DELTA_Y);
  249.  
  250.             Coef := CalculateTreeCoef(TreeRoot^.NextRight);
  251.             CalculateWidth(TreeRoot^.NextRight, X + Coef * DELTA_X, Y+DELTA_Y);
  252.         end;
  253.         if X < MinTreeCoord then
  254.             MinTreeCoord := X;
  255.  
  256.         if X > MaxTreeCoord then
  257.             MaxTreeCoord := X;
  258.     end;
  259. end;
  260.  
  261. function CalculateHeight(TreeRoot: TPointer): Integer;
  262. begin
  263.     CalculateHeight := FindMaxDepth(TreeRoot) * DELTA_Y + RADIUS + 70;
  264. end;
  265.  
  266. procedure EditImageSize(TreeStart: TPointer);
  267. var
  268.     CurrWidth, CurrHeight: Integer;
  269. begin
  270.     MinTreeCoord := 0;
  271.     MaxTreeCoord := 0;
  272.     CalculateWidth(TreeStart, 0, 0);
  273.  
  274.     CurrHeight := CalculateHeight(TreeStart);
  275.     CurrWidth := -MinTreeCoord + MaxTreeCoord + 2 * RADIUS + 100;
  276.  
  277.     with MainForm.TreeImage do
  278.     begin
  279.         if CurrWidth > DEFAULT_WIDTH then
  280.             Width := CurrWidth
  281.         else
  282.             Width := DEFAULT_WIDTH;
  283.  
  284.         if CurrHeight > DEFAULT_HEIGHT then
  285.             Height := CurrHeight
  286.         else
  287.             Height := DEFAULT_HEIGHT;
  288.     end;
  289. end;
  290.  
  291. procedure TMainForm.AddButtonClick(Sender: TObject);
  292. begin
  293.     AddElemToTree(StrToInt(ValueEdit.Text), TreeStart);
  294.     TreeImage.Picture := nil;
  295.     ValueEdit.Text := '';
  296.     EditImageSize(TreeStart);
  297.     if TreeStart <> nil then
  298.         DrawTree(TreeStart, -MinTreeCoord + RADIUS + 50, 70);
  299. end;
  300.  
  301. procedure TMainForm.DeleteButtonClick(Sender: TObject);
  302. begin
  303.     DeleteElemInTree(StrToInt(ValueEdit.Text), TreeStart);
  304.     ValueEdit.Text := '';
  305.     TreeImage.Picture := nil;
  306.     EditImageSize(TreeStart);
  307.     if TreeStart <> nil then
  308.         DrawTree(TreeStart, -MinTreeCoord + RADIUS + 50, 70);
  309. end;
  310.  
  311. procedure TMainForm.ProcessingButtonClick(Sender: TObject);
  312. begin
  313.     AnswerLabel.Caption := 'Длина наименьшего пути:' + IntToStr(FindMinDepth(TreeStart)-1);
  314.     EditTree(TreeStart);
  315.     TreeImage.Picture := nil;
  316.     EditImageSize(TreeStart);
  317.     if TreeStart <> nil then
  318.         DrawTree(TreeStart, -MinTreeCoord + RADIUS + 50, 70);
  319. end;
  320.  
  321. procedure TMainForm.SaveMenuItemClick(Sender: TObject);
  322. begin
  323.     if SavePictureDialog.Execute then
  324.         try
  325.             TreeImage.Picture.SaveToFile(SavePictureDialog.FileName);
  326.         except
  327.             MessageBox(MainForm.Handle, 'Не удалось сохранить файл!', 'Ошибка', MB_OK or MB_ICONERROR);
  328.         end;
  329. end;
  330.  
  331. function ReadNumFromFile(var FileIn: TextFile; var Num: Integer): Boolean;
  332. var
  333.     IsFileCorrect: Boolean;
  334.     NumStr: String;
  335.     Code: Integer;
  336.  
  337. begin
  338.     Readln(FileIn, NumStr);
  339.     Val(NumStr, Num, Code);
  340.  
  341.     if Code = 0 then
  342.         IsFileCorrect := True
  343.     else
  344.     begin
  345.         MessageBox(MainForm.Handle, 'Неверный формат данных в файле!', 'Ошибка', MB_OK or MB_ICONERROR);
  346.         IsFileCorrect := False;
  347.     end;
  348.  
  349.     if (IsFileCorrect) and ((Num < MIN_VALUE) or (Num > MAX_VALUE)) then
  350.     begin
  351.         MessageBox(MainForm.Handle, 'Неверный формат данных в файле!', 'Ошибка', MB_OK or MB_ICONERROR);
  352.         IsFileCorrect := False;
  353.     end;
  354.  
  355.     ReadNumFromFile := IsFileCorrect;
  356. End;
  357.  
  358. function CheckFile(var FileIn: TextFile): Boolean;
  359. var
  360.     IsFileCorrect: Boolean;
  361.     TempNum: Integer;
  362. begin
  363.     IsFileCorrect := True;
  364.  
  365.     try
  366.         Reset(FileIn);
  367.     except
  368.         IsFileCorrect := False;
  369.         MessageBox(MainForm.Handle, 'Не удалось открыть файл!', 'Ошибка', MB_OK Or MB_ICONERROR);
  370.     end;
  371.  
  372.     if IsFileCorrect then
  373.     begin
  374.         repeat
  375.             IsFileCorrect := ReadNumFromFile(FileIn, TempNum);
  376.         until not IsFileCorrect or EoF(FileIn);
  377.  
  378.         CloseFile(FileIn);
  379.     end;
  380.  
  381.     CheckFile := IsFileCorrect;
  382. end;
  383.  
  384. procedure TMainForm.OpenMenuItemClick(Sender: TObject);
  385. var
  386.     FileIn: TextFile;
  387.     Path: String;
  388.     TempNum: Integer;
  389. begin
  390.     if OpenDialog.Execute Then
  391.     begin
  392.         Path := OpenDialog.FileName;
  393.         AssignFile(FileIn, Path);
  394.  
  395.         if CheckFile(FileIn) then
  396.         begin
  397.             ClearTree(TreeStart);
  398.             TreeStart := CreateEmptyTree();
  399.  
  400.             Reset(FileIn);
  401.             repeat
  402.                 Readln(FileIn, TempNum);
  403.                 AddElemToTree(TempNum, TreeStart);
  404.             until EoF(FileIn);
  405.             CloseFile(FileIn);
  406.  
  407.             AnswerLabel.Caption := '';
  408.             ValueEdit.Text := '';
  409.             TreeImage.Picture := nil;
  410.             EditImageSize(TreeStart);
  411.             if TreeStart <> nil then
  412.                 DrawTree(TreeStart, -MinTreeCoord + RADIUS + 50, 70);
  413.         end;
  414.     end;
  415. end;
  416. end.
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430. unit BinaryTreeUnit;
  431.  
  432. interface
  433. type
  434.     TPointer = ^Elem;
  435.     Elem = record
  436.         Value: Integer;
  437.         NextLeft, NextRight: TPointer;
  438.     end;
  439.     PNodeList = ^NodeList;
  440.     NodeList = record
  441.         Value: Integer;
  442.         Next: PNodeList;
  443.     end;
  444.  
  445. function CreateEmptyTree(): TPointer;
  446. procedure AddElemToTree(const N: Integer; Var TreeStart: TPointer);
  447. procedure DeleteElemInTree(Const N: Integer; Var TreeStart: TPointer);
  448. procedure EditTree(var TreeStart: TPointer);
  449. procedure ClearTree(var TreeStart: TPointer);
  450. function FindMaxDepth(TreeStart: TPointer): Integer;
  451. function FindMinDepth(TreeStart: TPointer): Integer;
  452. function CalculateTreeCoef (TreeStart: TPointer): Integer;
  453. implementation
  454.  
  455. var
  456.     ListLastElem, ListCentralVertex: PNodeList;
  457.  
  458. function CreateEmptyTree(): TPointer;
  459. begin
  460.     CreateEmptyTree := nil;
  461. end;
  462.  
  463. procedure ClearTree(var TreeStart: TPointer);
  464. begin
  465.     if TreeStart <> nil then
  466.     begin
  467.         if (TreeStart^.NextLeft = nil) and (TreeStart^.NextRight = nil) then
  468.         begin
  469.             Dispose(TreeStart);
  470.             TreeStart := nil;
  471.         end
  472.         else if TreeStart^.NextLeft <> nil then
  473.             ClearTree(TreeStart^.NextLeft)
  474.         else if TreeStart^.NextRight <> nil then
  475.             ClearTree(TreeStart^.NextRight)
  476.         else
  477.         begin
  478.             ClearTree(TreeStart^.NextLeft);
  479.             ClearTree(TreeStart^.NextRight);
  480.         end;
  481.     end;
  482. end;
  483.  
  484. procedure AddElemToTree(const N: Integer; Var TreeStart: TPointer);
  485. begin
  486.     if TreeStart <> nil then
  487.     begin
  488.         if TreeStart^.Value > N then
  489.             AddElemToTree(N, TreeStart^.NextLeft)
  490.         else
  491.             if TreeStart^.Value < N then
  492.                 AddElemToTree(N, TreeStart^.NextRight);
  493.     end
  494.     else
  495.     begin
  496.         New(TreeStart);
  497.         TreeStart^.Value := N;
  498.         TreeStart^.NextRight := nil;
  499.         TreeStart^.NextLeft := nil;
  500.     end;
  501. end;
  502.  
  503. procedure FindMinElemInRightSubtree(var StartSubtree: TPointer);
  504. begin
  505.     while StartSubtree^.NextLeft <> nil do
  506.         StartSubtree := StartSubtree^.NextLeft;
  507. end;
  508.  
  509. procedure DeleteElemInTree(const N: Integer; var TreeStart: TPointer);
  510. var
  511.     Temp: TPointer;
  512. begin
  513.     if TreeStart <> nil then
  514.     begin
  515.         if TreeStart^.Value = N then
  516.         begin
  517.             Temp := TreeStart;
  518.             if TreeStart^.NextRight <> nil then
  519.             begin
  520.                 if TreeStart^.NextLeft = nil then
  521.                 begin
  522.                     TreeStart := TreeStart^.NextRight;
  523.                     Dispose(Temp);
  524.                 end
  525.                 else
  526.                 begin
  527.                     Temp := TreeStart^.NextRight;
  528.                     FindMinElemInRightSubtree(Temp);
  529.                     TreeStart^.Value := Temp^.Value;
  530.                     DeleteElemInTree (Temp^.Value, TreeStart^.NextRight);
  531.                 end;
  532.             end
  533.             else
  534.                 if TreeStart^.NextLeft <> nil then
  535.                 begin
  536.                     TreeStart := TreeStart^.NextLeft;
  537.                     Dispose(Temp);
  538.                 end
  539.                 else
  540.                 begin
  541.                     TreeStart := nil;
  542.                     Dispose(Temp);
  543.                 end;
  544.         end
  545.         else
  546.         begin
  547.             if TreeStart^.Value > N then
  548.                 DeleteElemInTree(N, TreeStart^.NextLeft)
  549.             else
  550.                 DeleteElemInTree(N, TreeStart^.NextRight);
  551.         end;
  552.     end;
  553. end;
  554.  
  555. function GetMin (A, B: Integer): Integer;
  556. begin
  557.     if A < B then
  558.         GetMin := A
  559.     else
  560.         GetMin := B;
  561. end;
  562.  
  563. function GetMax (A, B: Integer): Integer;
  564. begin
  565.     if A > B then
  566.         GetMax := A
  567.     else
  568.         GetMax := B;
  569. end;
  570.  
  571. function FindMinDepth(TreeStart: TPointer): Integer;
  572. var
  573.     MinDepth: Integer;
  574. begin
  575.     if TreeStart = nil then
  576.         MinDepth := 0
  577.     else if (TreeStart^.NextLeft = nil) and (TreeStart^.NextRight = nil) then
  578.         MinDepth := 1
  579.     else if TreeStart^.NextLeft = nil then
  580.         MinDepth := 1 + FindMinDepth(TreeStart^.NextRight)
  581.     else if TreeStart^.NextRight = nil then
  582.         MinDepth := 1 + FindMinDepth(TreeStart^.NextLeft)
  583.     else
  584.         MinDepth := 1 + GetMin(FindMinDepth(TreeStart^.NextLeft), FindMinDepth(TreeStart^.NextRight));
  585.  
  586.     FindMinDepth := MinDepth;
  587. end;
  588.  
  589. function FindMaxDepth(TreeStart: TPointer): Integer;
  590. var
  591.     MaxDepth, MaxR, MaxL: Integer;
  592. begin
  593.     if TreeStart = nil then
  594.         MaxDepth := 0
  595.     else
  596.     begin
  597.         MaxR := 1 + FindMaxDepth(TreeStart^.NextRight);
  598.         MaxL := 1 + FindMaxDepth(TreeStart^.NextLeft);
  599.  
  600.         MaxDepth := GetMax(MaxL, MaxR);
  601.     end;
  602.     FindMaxDepth := MaxDepth;
  603. end;
  604.  
  605. procedure AddNodeToList(const Value: Integer; Header: PNodeList);
  606. begin
  607.     while Header^.Next <> nil do
  608.         Header := Header^.Next;
  609.  
  610.     New(Header^.Next);
  611.     Header := Header^.Next;
  612.     Header^.Value := Value;
  613.     Header^.Next := nil;
  614. end;
  615.  
  616. procedure GetLeafsValue(TreeStart: TPointer; Depth: Integer);
  617. begin
  618.     if TreeStart <> nil then
  619.     begin
  620.         if (Depth = 1) and (TreeStart^.NextLeft = nil) and (TreeStart^.NextRight = nil) then
  621.         begin
  622.             AddNodeToList(TreeStart^.Value, ListLastElem);
  623.         end
  624.         else
  625.         begin
  626.             GetLeafsValue(TreeStart^.NextLeft, Depth - 1);
  627.             GetLeafsValue(TreeStart^.NextRight, Depth - 1);
  628.         end;
  629.     end;
  630. end;
  631.  
  632. function IsValueInList (const Value: Integer; Header: PNodeList): Boolean;
  633. var
  634.     IsElemInList: Boolean;
  635. begin
  636.     IsElemInList := False;
  637.     while (Header^.Next <> nil) and not IsElemInList do
  638.     begin
  639.         if Value = Header^.Next^.Value then
  640.             IsElemInList := True;
  641.  
  642.         Header := Header^.Next;
  643.     end;
  644.  
  645.     IsValueInList := IsElemInList;
  646. end;
  647.  
  648. procedure GetCentraVertexes(TreeStart: TPointer; Depth: Integer; const LeafValue: Integer);
  649. begin
  650.     if TreeStart <> nil then
  651.     begin
  652.         if Depth = 1 then
  653.         begin
  654.             if not IsValueInList(TreeStart^.Value, ListCentralVertex) then
  655.                 AddNodeToList(TreeStart^.Value, ListCentralVertex);
  656.         end
  657.         else
  658.         begin
  659.             if LeafValue < TreeStart^.Value then
  660.                 GetCentraVertexes(TreeStart^.NextLeft, Depth - 1, LeafValue)
  661.             else
  662.                 GetCentraVertexes(TreeStart^.NextRight, Depth - 1, LeafValue);
  663.         end;
  664.     end;
  665. end;
  666.  
  667. procedure DisposeList(Header: PNodeList);
  668. var
  669.     Temp: PNodeList;
  670. begin
  671.     while Header <> nil do
  672.     begin
  673.         Temp := Header;
  674.         Header := Header^.Next;
  675.         Dispose(Temp);
  676.     end;
  677. end;
  678.  
  679. procedure EditTree(var TreeStart: TPointer);
  680. var
  681.     MinDepth: Integer;
  682.     TempListPointer: PNodeList;
  683. begin
  684.     MinDepth := FindMinDepth(TreeStart);
  685.     if Odd(MinDepth) then
  686.     begin
  687.         New(ListLastElem);
  688.         ListLastElem^.Next := nil;
  689.  
  690.         GetLeafsValue(TreeStart, MinDepth);
  691.  
  692.         New(ListCentralVertex);
  693.         ListCentralVertex^.Next := nil;
  694.  
  695.         TempListPointer := ListLastElem^.Next;
  696.         repeat
  697.             GetCentraVertexes(TreeStart, (MinDepth + 1) div 2, TempListPointer^.Value);
  698.             TempListPointer := TempListPointer^.Next;
  699.         until TempListPointer = nil;
  700.  
  701.         TempListPointer := ListCentralVertex^.Next;
  702.         repeat
  703.             DeleteElemInTree(TempListPointer^.Value, TreeStart);
  704.             TempListPointer := TempListPointer^.Next;
  705.         until TempListPointer = nil;
  706.  
  707.         DisposeList(ListLastElem);
  708.         DisposeList(ListCentralVertex)
  709.     end;
  710. end;
  711.  
  712. function CountSoloElem(TreeStart: TPointer): Integer;
  713. var
  714.     CountL, CountR: Integer;
  715. begin
  716.     if TreeStart = Nil then
  717.         CountSoloElem := 0
  718.     Else
  719.     Begin
  720.         if (TreeStart^.NextLeft <> nil) and (TreeStart^.NextRight = nil) then
  721.             CountSoloElem := CountSoloElem(TreeStart^.NextLeft) + 1
  722.         Else if (TreeStart^.NextRight <> nil) and (TreeStart^.NextLeft = nil) then
  723.             CountSoloElem := CountSoloElem(TreeStart^.NextRight) + 1
  724.         Else
  725.         Begin
  726.             CountL := CountSoloElem(TreeStart^.NextLeft);
  727.             CountR := CountSoloElem(TreeStart^.NextRight);
  728.             if CountL > CountR then
  729.                 CountSoloElem := CountL
  730.             Else
  731.                 CountSoloElem := CountR;
  732.         End;
  733.     End;
  734. end;
  735.  
  736. function PowerNum (Num, Pow: Integer): Integer;
  737. var
  738.     I, Sum: Integer;
  739. begin
  740.     Sum := 1;
  741.     for I := Pow downto 1 do
  742.         Sum := Sum * Num;
  743.  
  744.     PowerNum := Sum;
  745. end;
  746.  
  747. function CalculateTreeCoef (TreeStart: TPointer): Integer;
  748. begin
  749.     CalculateTreeCoef := PowerNum(2, FindMaxDepth(TreeStart) - CountSoloElem(TreeStart))
  750. end;
  751.  
  752. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement