TikZ 节点部分子项

TikZ 节点部分子项

我知道如何使用在 TikZ 中创建多部分节点\nodepart,并且我知道如何从这些节点部分绘制线条以将它们连接到其他节点:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
    bnode/.style = {                                                     
        draw,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4
    }
}
\begin{document}
\begin{tikzpicture}
\node[bnode]
   (root)
   {      \nodepart{one}
      $12$ \nodepart{two}
      $15$ \nodepart{three}
      $20$ \nodepart{four}
      $\times$};

\draw[->]
    (root.south west) -- +(-4,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $3$ \nodepart{two}
            $9$ \nodepart{three}
            $10$ \nodepart{four}
            $12$};                           

\draw[->]
    (root.one split south) -- +(-2,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $13$ \nodepart{two}
            $14$ \nodepart{three}
            $15$ \nodepart{four}
            $\times$};

\draw[->]
    (root.two split south) -- +(0,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $17$ \nodepart{two}
            $18$ \nodepart{three}
            $\times$ \nodepart{four}
            $\times$};

\draw[->]
    (root.three split south) -- +(2,-1)
    node[bnode, anchor=north]
        (childnode)
        {      \nodepart{one}
            $21$ \nodepart{two}
            $29$ \nodepart{three}
            $\times$ \nodepart{four}
            $\times$};


\end{tikzpicture}
\end{document}

渲染:

在此处输入图片描述

即使在这个简单的例子中,我也必须计算子节点的正确位置,因为它们是重叠的。想象一下在树中添加另一个级别。这些计算将变得非常繁琐。

我知道 TikZ 有一些不错的树语法,可以轻松绘制树,但我没有立即看到它在这里如何应用。有没有办法使用 TikZ 的child语法来处理多部分节点,这样我就不必担心子节点的间距和位置。

需要澄清的是:多部分节点的每个部分都应该能够拥有它自己的适当的子节点,并且子节点本身也是多部分节点,而多部分节点又可以有多个子节点(每个节点部分一个)。

答案1

问题源于a'比 更宽a。因此,您可以设置text width=1.0em, align=center以确保每个节点的宽度相同:

在此处输入图片描述

代码:

\documentclass[border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\tikzset{
    bnode/.style = {   
        text width=1.0em, align=center,                                           
        draw,
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4
    }
}
\begin{document}
\begin{tikzpicture}
    \node[bnode]
       (root)
       {      \nodepart{one}
          $a$ \nodepart{two}
          $b$ \nodepart{three}
          $c$ \nodepart{four}
          $d$};

    \draw (root.one south) -- +(0,-1) node[draw, anchor=north](q) {$a'$};
    \draw (root.two south) -- +(0,-1) node[draw, anchor=north](q) {$b'$};
\end{tikzpicture}
\end{document}

答案2

经过近五年的时间......

使用calcchainpositioning库,节点之间的距离很容易确定。除此之外,代码也简短明了:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                calc, chains,
                positioning,
                shapes.multipart}

\begin{document}
    \begin{tikzpicture}[
  node distance = 13mm and 1mm,
    start chain = A going right,
mpn/.style args = {#1/#2/#3/#4}{draw,
    rectangle split, rectangle split horizontal,
    rectangle split parts=4,
    on chain=A,
    node contents={ \nodepart{one}    $#1$
                    \nodepart{two}    $#2$
                    \nodepart{three}  $#3$
                    \nodepart{four}   $#4$}
                                },
                        ]
\node[mpn=3/9/10/12];
\node[mpn=13/14/15/\times];
\node[mpn=17/18/\times/\times];
\node[mpn=21/29/\times/\times];
%
\node[mpn=12/15/20/\times,
      above=of $(A-1.north west)!0.5!(A-4.north east)$];
\foreach \i in {1,...,4}
\draw[-Stealth, semithick, shorten >=1mm, shorten <=1mm]
    (A-5) -- (A-\i.north);
    \end{tikzpicture}
\end{document}

在此处输入图片描述

这个两层树可以很容易地扩展到更多层。较低层的设计应与上面的 MWE 类似,较高层只是上面 MWE 顶层的重复。

附录: 利用该forest包你可以按照自己的意愿设计一棵树:

    \documentclass[tikz, margin=3mm]{standalone}
    \usetikzlibrary{arrows.meta,
                    shapes.multipart}
    \usepackage{forest}
    \newcommand\mpnc[4]{\nodepart{one}      $#1$
                        \nodepart{two}      $#2$                    
                        \nodepart{three}    $#3$
                        \nodepart{four}     $#4$}

    \begin{document}
        \begin{forest}
    for tree = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts=4,
        draw,
        %
        parent anchor=south,
        child anchor=north,
        edge = {-Stealth, semithick, shorten >=1mm, shorten <=1mm},
        l sep=12mm,
        s sep=1mm,
                }
    [{\mpnc{12}{15}{20}{\times}}
        [{\mpnc{3}{9}{12}{\times}}]
        [{\mpnc{13}{14}{15}{\times}}]
        [{\mpnc{17}{18}{\times}{\times}}]
        [{\mpnc{21}{29}{\times}{\times}}]
    ]
        \end{forest}
    \end{document}

在此处输入图片描述

答案3

不幸的是,这不是真正的答案。不过,如果时间还不算晚,我想分享我的一个解决方案。

它不是很好,可以改进,但我希望它能以某种方式帮助你。:)

编辑\tikzstyle取而代之\tikset

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}

\usepackage{tikz}
\usetikzlibrary{arrows, shapes, trees, calc, positioning}
\tikzset{
    key/.style = {
        circle,
        fill = white,
        dotted,
        thick,
        draw,
    },
    vazio/.style = {
        draw = none,
        fill = none,
    },
    no/.style = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts = #1,
        rectangle split draw splits = false,
        rounded corners,
        fill = black!15,
        draw = black!85,
        thick,
        anchor = center,
        minimum height = 1.8em,
    },
    no b/.style = {
        rectangle split,
        rectangle split horizontal,
        rectangle split parts = #1,
        rectangle split empty part width = 1.3ex,
        rectangle split draw splits = false,
        rounded corners,
        fill = black!15,
        draw = black!85,
        thick,
        anchor = center,
        minimum height = 1.8em,
    }, 
    edge from parent/.style = {
        thick,
        -latex,
        draw = black,
    },
    child/.style = {
        edge from parent path = {(\tikzparentnode.west)
            ++(0.06cm+#1*0.65cm, -0.18cm) -- (\tikzchildnode)},
    },
    nil/.style = {
        edge from parent = {thick, -square, draw = gray},
    },
}

\begin{document}

\begin{tikzpicture}[scale = 0.65, transform shape]
    \tikzstyle{every node} = [no b]
    \tikzstyle{level 1} = [sibling distance = 12cm]
    \tikzstyle{level 2} = [sibling distance = 3cm]
    \node (tree) {42}
        child[child = 0] {node {19 \nodepart{two} 33}
            child[child = 0] {node {10 \nodepart{two} 15 \nodepart{three} 16
                \nodepart{four} 18}}
            child[child = 1] {node {22 \nodepart{two} 27 \nodepart{three} 29}}
            child[child = 2] {node {35 \nodepart{two} 40 \nodepart{three} 41}}
        }
        child[child = 1] {node {61 \nodepart{two} 74 \nodepart{three} 85 
                \nodepart{four} 95}
            child[child = 0] {node {47 \nodepart{two} 49 \nodepart{three} 53}}
            child[child = 1] {node {65 \nodepart{two} 68 \nodepart{three} 72}}
            child[child = 2] {node {77 \nodepart{two} 81}}
            child[child = 3] {node {88 \nodepart{two} 90 \nodepart{three} 93
                \nodepart{four} 94}}
            child[child = 4] {node {97 \nodepart{two} 98}}
        }
    ;
    \draw [latex-, thick] (tree) -- ++ (0, 1);
\end{tikzpicture}

\end{document}

相关内容