树中各层节点之间的距离相等

树中各层节点之间的距离相等

我有一棵树,但希望每一层矩形之间的距离相等(每一层矩形之间的间距相等)。树的构思来自这里:在图中添加额外的有向弧(tikz 图片) 我需要调整距离。如能得到帮助我将不胜感激!

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.multipart}
\usepackage{tikz}
\tikzset{block/.style={
        font=\sffamily,
        draw=black,
        thin,
        fill=white!50,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=#1,
        outer sep=0pt},
        }

\begin{document}
    
\def\lvld{1.2}                  % Choose level distance

\begin{figure*}[h]
\begin{tikzpicture}[level distance=\lvld cm,
                        level 1/.style={sibling distance=5cm}, %level B
                        level 2/.style={sibling distance=3.7cm}, %level c
                        level 3/.style={sibling distance= 1.9cm},
                        edgedown/.style={edge from parent/.style={draw=black,thick,-latex}}]
        \node[block=1][label=right:{(0,0)}] (A) {(1,1,1)}
            [grow=down,edgedown]
            child {node[block=1][label=right:{(0,0)}] (B1) {(2,2,2)}
                child {node[block=1][label=left:{(0,0)}] (C1) {(5,5,5)}  
                    child {node[block=1][label=left:{(0,0)}] (D1) {(11,11,11)}}
                    child {node[block=1][label=right:{(0,0)}] (D2) {(12,12,12)}} }                
                child {node[block=1][label=right:{(0,0)}] (C2) {(6,6,6)} 
                    child {node[block=1][label=right:{(0,0)}] (D3) {(13,13,13)}}
                    child {node[block=1][label=right:{(0,0)}] (D4) {(14,14,14)}
                        child {node[block=1][label=right:{(0,0)}] (E1) {(19,19,19)}}}}
                child {node[block=1][label=right:{(0,0)}] (C3) {(7,7,7)}  
                    child {node[block=1][label=right:{(0,0)}] (D5) {(15,15,15)}}}}
            child {node[block=1][label=right:{(0,0)}] (B2) {(3,3,3)}
                child {node[block=1][label=right:{(0,0)}] (C4) {(8,8,8)}       }}
            child {node[block=1][label=right:{(0,0)}] (B3) {(4,4,4)}
                child {node[block=1][label=right:{(0,0)}] (C5) {(9,9,9)}   
                    child {node[block=1][label=right:{(0,0)}] (D6) {(16,16,16)}}}
                child {node[block=1][label=right:{(0,0)}] (C6) {(10,10,10)}            
                    child {node[block=1][label=right:{(0,0)}] (D7) {(17,17,17)}}
                    child {node[block=1][label=right:{(0,0)}] (D8) {(18,18,18)}}}};        
\end{tikzpicture}
\end{figure*}
\end{document}

答案1

虽然不完全是所需的结果,但是由于您使用链接了解决方案forest,因此我将您的树转换为了森林。

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{shapes.multipart}
\usepackage{tikz}
\tikzset{block/.style={
        font=\sffamily,
        draw=black,
        thin,
        fill=white!50,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=#1,
        outer sep=0pt},
        }

\usepackage{forest}

\def\lvld{1.2cm}                  % Choose level distance

\begin{document}
\begin{forest}
   for tree={draw=black, s sep=1cm, l sep=\lvld,
    edge={draw=black,thick,-latex}},
  [{(1,1,1)}, label=right:{(0,0)}
    [{(2,2,2)}, label=right:{(0,0)}
        [{(5,5,5)}, label=left:{(0,0)}
            [{(11,11,11)}, label=left:{(0,0)}]
            [{(12,12,12)}, label=right:{(0,0)}]
        ]
        [{(6,6,6)}, label=right:{(0,0)}
            [{(13,13,13)}, label=right:{(0,0)}]
            [{(14,14,14)}, label=right:{(0,0)}
                [{(19,19,19)}, label=right:{(0,0)}]
            ]
            [{(7,7,7)}, label=right:{(0,0)}
                [{(15,15,15)}, label=right:{(0,0)}]
            ]
        ]
    ]
    [{(3,3,3)}, label=right:{(0,0)}
       [{(8,8,8)}, label=right:{(0,0)}]
    ]
    [{(4,4,4)}, label=right:{(0,0)}
        [{(9,9,9)}, label=right:{(0,0)}
            [{(16,16,16)}, label=right:{(0,0)}]
        ]
        [{(10,10,10)}, label=right:{(0,0)}
            [{(17,17,17)}, label=right:{(0,0)}]
            [{(18,18,18)}, label=right:{(0,0)}]
        ]
    ]
]
\end{forest}
\end{document}

转化为森林

答案2

我不完全理解这个问题,但我认为您要求的是让每个级别的节点在水平方向上均匀分布。如果是这样,我认为这不是您想要的,甚至可能不是您想要的。下面的第二个示例半心半意地尝试实现该要求,以说明您可能不想要它的原因。基本上,除非您有一棵高度对称的树,否则结果看起来会很糟糕,树会变得不切实际地宽。要么这样,要么边缘(父节点和其子节点之间的线)会出现各种奇怪的角度。如果这真的是您想要的,我建议根本不要画树,而是使用类似的东西,matrix of nodes然后添加边缘。

下面的第一个示例是 jlab 提供的代码的简化版本。它试图在对称性和整洁性之间取得平衡。它是否能达到这种平衡尚有争议,但在我看来,结果看起来是合理的。

如上所述,第二个示例在某种程度上均衡了同一级别上节点之间的水平空间。它只对具有相同父节点的节点执行此操作,但即便如此,您仍可以看到树变得多么不平衡。要均衡同一级别上所有节点之间的间距,需要进一步拉伸树,并允许从根到的路径((3,3,3)例如(8,8,8))奇怪地曲折。这是可行的,但我认为这样做没有任何价值。

第三个示例使用了库forked edges中的edges元素。它使用了垂直向下、垂直穿过和垂直向下的边。因此,不匹配的角度被消除了,但树仍然非常紧凑。如果这是一个选项,您可以根据需要进一步调整间距,但这种风格在您的学科中可能可接受也可能不可接受。

第四个示例使用 来matrix of nodes演示如何在矩阵中设置节点。它不强加所要求的间距均衡。相反,它演示了您可以用来根据需要调整间距的方法。如果您希望总体上有更多的空间,请增加column sep。如果您希望特定列之间有更多空间,请向第一行添加额外间距,如示例中第 7 列和第 8 列所示。通过命名矩阵m,您可以使用形式的名称添加箭头(m-<row>-<column>),如矩阵设置后的循环所示\foreach。在调整矩阵时添加很有用,nodes in empty cells因为它为您提供了所有内容的参考。对箭头进行排序后,只需删除添加即可摆脱所有空白处的方块(这只是 的效果nodes={draw})。

我不知道这些树中的哪一种可能适合或不适合你的目的。

\documentclass[tikz,border=3.14mm]{standalone}
% ateb: https://tex.stackexchange.com/a/714369/ addaswyd o ateb jlab: https://tex.stackexchange.com/a/713651/ a chwestiwn Vika: https://tex.stackexchange.com/q/713642/
\usetikzlibrary{arrows.meta,matrix}
\usepackage{tikz}
\tikzset{%
  block/.style={
    font=\sffamily,
    draw=black,
    thin,
    fill=white!50,
    outer sep=0pt,
  },
}

\usepackage[edges]{forest}
\forestset{%
  declare toks={my label}{},
  declare boolean={my label done}{0},
  equalise s sep/.style={%
    for tree={%
      edge+={-Latex},
      anchor=base,
      align=@{}c@{},
      font=\sffamily,
    },
  },
  equalise node widths/.style={%
    before packing={%
      tempdima/.max={ > OOw2+d {max x}{min x}{##1-##2} }{tree},
      for tree={%
        minimum width/.register=tempdima,
      },
      typeset nodes,
    },
  },
  calign central child or midpoint/.style={%
    before typesetting nodes={%
      where={ > Ow+P {n children}{isodd(##1)} }
      {%
        calign primary child/.process={ Ow+P {n children}{int((##1+1)/2)}},
        calign=child edge,
      }{%
        calign=edge midpoint,
      },
    },
  },
  my labels/.style={%
    before typesetting nodes={%
      for nodewalk={%
        root,
        label/.process={ Ow{my label}{[my label style]left:{##1}}},
        last leaf,
        label/.process={ Ow{my label}{[my label style]below:{##1}}},
        fit=band,
        while nodewalk valid={previous leaf}{%
          previous leaf,
          label/.process={ Ow{my label}{[my label style]below:{##1}}},
        },
        while nodewalk valid={parent}{%
          parent,
          label/.process={ Ow{my label}{[my label style]left:{##1}}},
        },
      }{my label done},
      where my label done={}{%
        label/.process={ Ow{my label}{[my label style]right:{##1}}},
      },
    },
  },
  equalise s sep by level/.style={%
    before computing xy={%
      for tree children-first={%
        if={ > On> {n children}{1} }{%l[1] l[2]
          tempdima={ > Ow+d  O  > ? p {!first.s}{-##1} {!last.s} {Ow+d{!first.s}{-##1}} {O{!last.s}} },
          !first.s=-\foresteregister{tempdima},
          !last.s/.register=tempdima,
        }{},
      },
    },
  },
  /tikz/my label style/.style={font=\sffamily},
}

\begin{document}

\begin{forest}
  for tree={%
    block,
    s sep'=30pt, 
    l sep'=20pt,
    edge+={draw=black,thick,-Latex},
    font=\sffamily,
  },
  equalise node widths,
  calign central child or midpoint,
  my labels,
  [{(1,1,1)}, my label={(0,0)}
    [{(2,2,2)}, my label={(0,0)}
      [{(5,5,5)}, my label={(0,0)}
        [{(11,11,11)}, my label={(0,0)}]
        [{(12,12,12)}, my label={(0,0)}]
      ]
      [{(6,6,6)}, my label={(0,0)}
          [{(13,13,13)}, my label={(0,0)}]
          [{(14,14,14)}, my label={(0,0)}
            [{(19,19,19)}, my label={(0,0)}]
          ]
          [{(7,7,7)}, my label={(0,0)}
            [{(15,15,15)}, my label={(0,0)}]
          ]
      ]
    ]
    [{(3,3,3)}, my label={(0,0)}
      [{(8,8,8)}, my label={(0,0)},fit=band]
    ]
    [{(4,4,4)}, my label={(0,0)}
      [{(9,9,9)}, my label={(0,0)}
        [{(16,16,16)}, my label={(0,0)}]
      ]
      [{(10,10,10)}, my label={(0,0)}
        [{(17,17,17)}, my label={(0,0)}]
        [{(18,18,18)}, my label={(0,0)}]
      ]
    ]
  ]
\end{forest}
\begin{forest}
  for tree={%
    block,
    s sep'=30pt, 
    l sep'=20pt,
    edge+={draw=black,thick,-Latex},
    font=\sffamily,
  },
  equalise node widths,
  calign central child or midpoint,
  equalise s sep by level, 
  my labels,
  [{(1,1,1)}, my label={(0,0)}
    [{(2,2,2)}, my label={(0,0)}
      [{(5,5,5)}, my label={(0,0)}
        [{(11,11,11)}, my label={(0,0)}]
        [{(12,12,12)}, my label={(0,0)}]
      ]
      [{(6,6,6)}, my label={(0,0)}
          [{(13,13,13)}, my label={(0,0)}]
          [{(14,14,14)}, my label={(0,0)}
            [{(19,19,19)}, my label={(0,0)}]
          ]
          [{(7,7,7)}, my label={(0,0)}
            [{(15,15,15)}, my label={(0,0)}]
          ]
      ]
    ]
    [{(3,3,3)}, my label={(0,0)}
      [{(8,8,8)}, my label={(0,0)},fit=band]
    ]
    [{(4,4,4)}, my label={(0,0)}
      [{(9,9,9)}, my label={(0,0)}
        [{(16,16,16)}, my label={(0,0)}]
      ]
      [{(10,10,10)}, my label={(0,0)}
        [{(17,17,17)}, my label={(0,0)}]
        [{(18,18,18)}, my label={(0,0)}]
      ]
    ]
  ]
\end{forest}
\begin{forest}
  for tree={%
    block,
    s sep'=30pt, 
    l sep'=20pt,
    edge+={draw=black,thick,-Latex},
    font=\sffamily,
  },
  equalise node widths,
  calign central child or midpoint,
  my labels,
  forked edges,
  [{(1,1,1)}, my label={(0,0)}
    [{(2,2,2)}, my label={(0,0)}
      [{(5,5,5)}, my label={(0,0)}
        [{(11,11,11)}, my label={(0,0)}]
        [{(12,12,12)}, my label={(0,0)}]
      ]
      [{(6,6,6)}, my label={(0,0)}
          [{(13,13,13)}, my label={(0,0)}]
          [{(14,14,14)}, my label={(0,0)}
            [{(19,19,19)}, my label={(0,0)}]
          ]
          [{(7,7,7)}, my label={(0,0)}
            [{(15,15,15)}, my label={(0,0)}]
          ]
      ]
    ]
    [{(3,3,3)}, my label={(0,0)}
      [{(8,8,8)}, my label={(0,0)},fit=band]
    ]
    [{(4,4,4)}, my label={(0,0)}
      [{(9,9,9)}, my label={(0,0)}
        [{(16,16,16)}, my label={(0,0)}]
      ]
      [{(10,10,10)}, my label={(0,0)}
        [{(17,17,17)}, my label={(0,0)}]
        [{(18,18,18)}, my label={(0,0)}]
      ]
    ]
  ]
\end{forest}
\begin{tikzpicture}
  \node (m) [%
  matrix of nodes,
  nodes={draw,font=\sffamily},
  row sep=10mm,
  column sep=5mm,]
  {
    & & & & && |[label=left:{(0,0)}]| (1,1,1) &[10mm] &[10mm] &  & \\
    & & & |[label=left:{(0,0)}]| (2,2,2) & && |[label=right:{(0,0)}]| (3,3,3) & & & |[label=right:{(0,0)}]| (4,4,4) & \\
    & |[label=left:{(0,0)}]| (5,5,5) & & & |[label=right:{(0,0)}]| (6,6,6) && |[label=right:{(0,0)}]| (8,8,8) & & |[label=right:{(0,0)}]| (9,9,9) & & |[label=right:{(0,0)}]| (10,10,10) \\
    |[label=left:{(0,0)}]| (11,11,11)  & & |[label=right:{(0,0)}]| (12,12,12) & |[label=right:{(0,0)}]| (13,13,13) & |[label=right:{(0,0)}]| (14,14,14) & |[label=right:{(0,0)}]| (7,7,7) && & |[label=right:{(0,0)}]| (16,16,16) & |[label=right:{(0,0)}]| (17,17,17) && |[label=right:{(0,0)}]| (18,18,18) \\
    & & & & |[label=right:{(0,0)}]| (19,19,19) & |[label=right:{(0,0)}]| (15,15,15) && & & & & \\
  };
  \begin{scope}[every path/.style={draw,-Latex}]
    \foreach \i/\j in {1-7/2-7,2-7/3-7,1-7/2-4,1-7/2-10,2-4/3-2,3-2/4-1,3-2/4-3,2-4/3-5,3-5/4-4,3-5/4-5,3-5/4-6,4-5/5-5,4-6/5-6,2-10/3-9,2-10/3-11,3-11/4-12,3-11/4-10,3-9/4-9} \path (m-\i) -- (m-\j);
  \end{scope}
\end{tikzpicture}

\end{document}

[显然需要图像,但是由于 Okular 错误,必须等待。]

相关内容