mytree.pas 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. Uses CRT;
  2. Type
  3. UT = char; {Пользовательский тип}
  4. PBTree = ^TBTree; {Указатель на дерево}
  5. TBTree = record {Просто дерево}
  6. info : UT; {Значение}
  7. count: word; {Количество}
  8. Left : PBTree; {Левая ветвь}
  9. Right: PBTree; {Правая ветвь}
  10. end;
  11. Function NewChild(info:UT) : PBtree; {Функция создания новой ветви}
  12. var
  13. ne : PBTree; {Указатель на результат}
  14. begin
  15. New(ne);
  16. Ne^.info := Info; {Заполняем зн-е}
  17. Ne^.Left := nil;
  18. Ne^.Right := nil;
  19. Ne^.count := 1; {Кол-во - 1}
  20. NewChild := ne;
  21. end; {NewChild}
  22. {---------------------------------}
  23. Procedure DelBranch(br:PBTree); {Удаление ветви, вмести с детьми}
  24. begin
  25. if br^.left <> nil then DelBranch(br^.left); {Если есть левый ребенок -
  26. удаляем его}
  27. if br^.right <> nil then DelBranch(br^.right);{А если есть и правый - и
  28. его тоже!}
  29. Dispose(br); {Собственно удаление}
  30. end;{DelBranch}
  31. {---------------------------------}
  32. Procedure SetLRootRInfo(info:UT;Br:PBTree); {Добавление нового зн-я на
  33. на ветвь}
  34. begin
  35. if info < Br^.info then {Посылаем на лево}
  36. begin
  37. if (Br^.Left=nil) then Br^.Left := NewChild(info) {Если никого - вешаем}
  38. else SetLRootRInfo(info,BR^.Left); {Иначе - спускаем на лево}
  39. end
  40. else {А если такой-же - увеличиваем кол-во}
  41. if (info=Br^.info) then inc(Br^.count)
  42. else {Значит оно - справа}
  43. begin
  44. if (Br^.Right=nil) then {Если никого - вешаем направо}
  45. Br^.Right := NewChild(info)
  46. else SetLRootRInfo(info,BR^.Right); {Иначе - спускаем на право}
  47. end;
  48. end;{SetLRootRInfo}
  49. {---------------------------------}
  50. Function MakeLRootRTree(st:string;count:word):PBTree;
  51. {Создание двоичного дерева для поиска}
  52. var
  53. ret : PBTree;
  54. pos : byte;
  55. Begin
  56. ret := NewChild(st[1]);
  57. for pos := 2 to count do SetLRootRInfo(st[pos],ret);
  58. MakeLRootRTree := ret;
  59. End; {MakeLRootRTree}
  60. {---------------------------------}
  61. var
  62. h : word; {Глобальная переменная - номер уровня}
  63. Procedure FindInfo(info:UT;Br:PBTree); {Поиск зн-я в дереве, с подсчетом H}
  64. begin
  65. if (Br<>nil) then begin
  66. if (info<Br^.Info) then begin inc(h); FindInfo(info,Br^.Left) end
  67. else if (info>Br^.Info) then begin inc(h); FindInfo(info,Br^.Right) end;
  68. end
  69. else h := 0;
  70. end;{FindInfo}
  71. {---------------------------------}
  72. Function GetHeight(BTree:PBTree):word;
  73. var
  74. max,h : word;
  75. Procedure Calc(Br:PBtree);
  76. begin
  77. if Br <> nil then
  78. begin
  79. inc(h);
  80. Calc(Br^.Left);
  81. Calc(Br^.Right);
  82. dec(h);
  83. end
  84. else
  85. begin
  86. if h > max then max := h;
  87. end;
  88. end;
  89. begin
  90. max := 0;
  91. h := 0;
  92. Calc(BTree);
  93. GetHeight := max;
  94. end;{GetHeight}
  95. {---------------------------------}
  96. Procedure ShowTree(Tree:PBTree);
  97. var x,y : byte;
  98. {-=-=-=-=-=-=-}
  99. procedure WriteBranch(Br:PBTree;x,y:byte);
  100. begin
  101. GotoXY(x,y);
  102. TextColor(BLue);
  103. Write(BR^.Info);
  104. TextColor(LightGray);
  105. GotoXY(x,y+1);
  106. if (Br^.Left<>nil) and (Br^.Right<>nil) then
  107. begin
  108. Write('╧');
  109. GotoXY(x-6,y+1);
  110. Write('╒═════');
  111. WriteBranch(Br^.Left,x-6,y+2);
  112. GotoXY(x+1,y+1);
  113. Write('═════╕');
  114. WriteBranch(Br^.Right,x+6,y+2);
  115. end
  116. else
  117. if (Br^.Left=nil) and (Br^.Right<>nil) then
  118. begin
  119. Write('╘═════╕');
  120. WriteBranch(Br^.Right,x+6,y+2);
  121. end
  122. else if (Br^.Left<>nil) and (Br^.Right=nil) then
  123. begin
  124. GotoXY(x-6,y+1);
  125. Write('╒═════╛');
  126. WriteBranch(Br^.Left,x-6,y+2);
  127. end;
  128. end;
  129. {-=-=-=-=-=-=-}
  130. begin
  131. if GetHeight(Tree) > 10 Then begin WriteLn('Tree to high!');exit;end;
  132. x := 40;
  133. y := 1 ;
  134. ClrScr;
  135. WriteBranch(Tree,x,y);
  136. end;{ShowTree}
  137. {---------------------------------}
  138. Var
  139. test : string;
  140. BTree : PBTree;
  141. ch : char;
  142. BEGIN
  143. ClrScr;
  144. WriteLn('Введите массив для создания двоичного дерева поиска методом Left->Root->Right');
  145. ReadLn(test);
  146. BTree := MakeLRootRTree(test,Length(test));
  147. { WriteLn('Высота дерева: ',GetHeight(BTree));
  148. WriteLn('Введите символ для поиска по дереву: ');
  149. ch := ReadKey;
  150. h := 1;
  151. FindInfo(ch,BTree);
  152. if (h<>0) then
  153. WriteLn('Символ ''',ch,''' найден на ',h,'-ом уровне')
  154. else
  155. WriteLn('Символ ''',ch,''' не найден');
  156. WriteLn('Press any key to view tree');
  157. ReadKey;}
  158. ShowTree(Btree);
  159. DelBranch(BTree);
  160. ReadKey;
  161. END.