Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Дерево


Автор: Still 17.11.2007, 00:04
Мне нужно построить бинарное дерево в графическом виде. Какие компоненты посоветуете использовать для этого?

Автор: Alexeis 17.11.2007, 01:04
Я в универе писал такой компонент можно глянуть тут описание файлы и примеры http://alexei-s1.narod.ru/1.htm

Автор: aktuba 17.11.2007, 03:05
Цитата(Still @  17.11.2007,  01:04 Найти цитируемый пост)
Мне нужно построить бинарное дерево в графическом виде. Какие компоненты посоветуете использовать для этого? 

Вообще вопроса не понял. Построить дерево - море компонентов, от TReeView до TVirtualTreeView...

Автор: Still 20.11.2007, 01:43
Опишу чуть подробнее.

Дана произвольная математическая формула. Для построения дерева нужно получить центральный знак (+ | - | * | /) с наименьшим приоритетом и взять его за самый первый (верхний) узел дерева. Далее идет разбивка на две ветви (левая и правая ветви от верхнего узла), каждая из которых по тому же принципу разделяет следующие операции. Покажу на примере.

Есть формула: 
a*b-(c+d)-h

Дерево формулы:
           -
       /       \
      *        -
     /  \     /  \
   a   b  h   +
                 /  \
                c  d

Как узнать, что за чем идет это не сложно. Проблема в графическом отображении дерева.

Автор: WaReZMEN 20.11.2007, 03:41
Still, Напиши клас в каждого узла по две ветки... и создоваи рекурсивно...

Автор: aktuba 20.11.2007, 14:43
Цитата(Still @  20.11.2007,  02:43 Найти цитируемый пост)
Проблема в графическом отображении дерева. 

Какая проблема? Отрисовать линии, символы на холсте?

Автор: Still 20.11.2007, 18:40
aktuba
Цитата
 Какая проблема? Отрисовать линии, символы на холсте? 


Угу. Вроде уже разобрался, но все равно не откажусь от совета.

Автор: WaReZMEN 21.11.2007, 01:19
Вот кусок правда это не совсем дерево но если расширить растояние между узлами получится что нужно...

Код

  TOrient=(orRigth,orUp,orNone);
  TCircleType=(ctFinish,ctRigthTop);

  TCell=Record
     LenLeft:Integer;
     LenTop:Integer;
     LenRight:Integer;
     LenBottom:Integer;
     X,Y:Integer;
     Size:Integer;
     SelectColor:TColor;
  End;

  TPathCell=Record
    Value:Integer;
    Orient:TOrient;
    isOptimal:Boolean;
  End;

  TMap=array of array of TCell;

  TMapPath=array of array of TPathCell;
   TCircle=Class;

  TCircleMng=class
    Private
      N,M:Integer;
    Public
    Path:TMapPath;
    Canvas:TCanvas;
    SeverLen:Integer;
    Map:TMap;
    Finish:TCircle;
    Start:TCircle;
    OptimalColor:TColor;

    constructor Create(xN,xM:Integer);
    Procedure Draw;
    Procedure CreateOptimalPath;
    Procedure Recalc(xCircle:TCircle);
  end;

  TCircle=Class
     private
       X1,Y1,X2,Y2,Radius:Integer;
     public
       OrientArrow:TOrient;
       Value:Integer;
       FillColor:TColor;
       LeftTop:TCircle;
       RigthButtom:TCircle;

       CircleType:TCircleType;
       Parent:TCircle;

       Sum:Integer;
       LenTop,LenRigth:Integer;
       LenPreor:Integer;
       Visible:Boolean;
       I,J:Integer;
       Start:Boolean;
       CircleMng:TCircleMng;
       constructor Create(xCircleMng:TCircleMng; xI,xJ:Integer;xCircleType:TCircleType;xParent:TCircle;xLenPreor:Integer;xOrientArrow:TOrient);

       procedure SaveCost(xOrientArrow:TOrient);
       Procedure Draw;
       Procedure DrawArrow;
  End;

.......


procedure TCircle.Draw;
Var
  OldBrushStyle:TBrushStyle;
  OldBrushColor:TColor;
  OldPenColor:TColor;
  Canvas:TCanvas;
begin
  IF (Visible=True) and (CircleType<>ctFinish) Then
    Begin
      Canvas:=CircleMng.Canvas;
      OldBrushStyle:=Canvas.Brush.Style;
      OldBrushColor:=Canvas.Brush.Color;
      OldPenColor:=Canvas.Pen.Color;
      Canvas.Brush.Style := bsSolid;
      IF CircleMng.Path[I,J].isOptimal Then
         FillColor:=CircleMng.OptimalColor
      Else
         FillColor:=Defcolor;
      Canvas.Brush.Color:=FillColor;
      Canvas.Ellipse(X1,Y1,X2,Y2);
      DrawArrow;
      Canvas.TextOut(X1+Round(Radius/2),Y1+Round(Radius/2),IntToStr(CircleMng.Path[I,J].Value));
      Canvas.Brush.Style := OldBrushStyle;
      Canvas.Brush.Color:=OldBrushColor;
      Canvas.Pen.Color:= OldPenColor;
    End;
   IF LeftTop<>Nil Then LeftTop.Draw;
   IF RigthButtom<>Nil Then RigthButtom.Draw;     
end;



procedure TCircle.DrawArrow;
Var
  Canvas:TCanvas;
  OldBrushStyle:TBrushStyle;
  OldBrushColor:TColor;
  OldPenColor:TColor;
begin
  IF Visible=True Then
    Begin
      Canvas:=CircleMng.Canvas;
      OldBrushStyle:=Canvas.Brush.Style;
      OldBrushColor:=Canvas.Brush.Color;
      OldPenColor:=Canvas.Pen.Color;
      Canvas.Brush.Style := bsSolid;
      IF CircleMng.Path[I,J].Orient=orRigth Then
        Begin
          Canvas.Pen.Color:=clGray;
          Canvas.MoveTo(X1+Round(Radius*2)-2,Y1+Round(Radius)-5);
          Canvas.LineTo(X1+Round(Radius*2)+5,Y1+Round(Radius));
          Canvas.LineTo(X1+Round(Radius*2)-2,Y1+Round(Radius)+5);
          Canvas.LineTo(X1+Round(Radius*2)-2,Y1+Round(Radius)-5);
          Canvas.Brush.Color:=clBlack;
          Canvas.FloodFill(X1+Round(Radius*2),Y1+Round(Radius),clGray,fsBorder);
          Canvas.Brush.Color:=FillColor;
          Canvas.Pen.Color:=OldPenColor;
        End;
      IF CircleMng.Path[I,J].Orient=orUp Then
        Begin
          Canvas.Pen.Color:=clGray;
          Canvas.MoveTo(X1+Radius-5,Y1);
          Canvas.LineTo(X1+Radius,Y1-5);
          Canvas.LineTo(X1+Radius+5,Y1);
          Canvas.LineTo(X1+Radius-5,Y1);
          Canvas.Brush.Color:=clBlack;
          Canvas.FloodFill(X1+Radius-2,Y1-2,clGray,fsBorder);
          Canvas.Brush.Color:=FillColor;
          Canvas.Pen.Color:=OldPenColor;
        End;
      Canvas.Brush.Style := OldBrushStyle;
      Canvas.Brush.Color:=OldBrushColor;
    End;
end;

 Вот скрин 



Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)