在计算机相关的文章中,树状图是最常见的几种图之一。树状图经常被用来用来演示结构、层次、算法等内容。而二叉树是最基础的树状图之一,掌握二叉树的画法就可以用图像展示一些算法或者数据结构了。
在 LaTeX 中,tikz
和tikz-qtree
两个包被用于绘制树状图,它们可以很方便的做出树状图来。。
tikz
是 LaTeX 中一个用来绘制图的包,使用 Alexis Dimitriadis’ Qtree 语法。而tikz-qtree
则是在tikz
的基础上做出的一个专门绘制树状图的包,比如给 Qtree 增添了很多功能,以及在 pdfTEX 和 XƎTEX 上支持pst-qtree
。
先来介绍一下如何在 TikZ 中绘制树状图。按照树、森林、二叉树的大致顺序介绍,因为二叉树比较简单,但是有足够展示各种使用方法。
如果你想查阅其他 TikZ 语法,可以查阅一个非官方的在线文档:[https://tikz.dev]。(https://tikz.dev)
首先,LaTeX 文件的代码结构如下:
%自定义类型和格式
\documentclass[10pt]{article}
%导入tikz包
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
%在这里输入绘制树的代码
\end{tikzpicture}
\end{document}
下面演示的所有的代码,除非特殊说明,不然都是放在上述结构中的%在这里输入绘制树的代码
的位置。
绘制树的语句由表示树开始的\node
、节点信息和表示一颗树结束的分号;
组成。大括号里写的是节点名称和信息。
比如下面这个语句会生成一颗有四个叶节点的树:
\node
%这里的parent是要显示的文本内容
{parent}
%这里的child表示是子节点,而后面的child 1才是要显示的文本内容
child {node {child 1}}
child {node {child 2}}
child {node {child 3}}
child {node {child 4}}
;
上文说到,\node
表示树的开始,分号;
表示树的结束。所以直接有几棵树写几段树的语句即可。只需要注意森林中每棵树的位置即可。
例如:
\node
{parent}
child {node {child 1}}
child {node {child 2}}
child {node {child 3}}
child {node {child 4}}
;
\node at (0,2)
{z}
child {node {a}}
child {node {b}}
child {node {3}}
child {node {4}}
;
一棵基础的二叉树由一个父节点和两个字节点构成,生成代码如下:
\node
{parent}
child {node {child 1}}
child {node {child 2}}
;
如果想自定义颜色,在父节点类型{parent}
前面或子节点类型名称child
后面加个[]
,然后将颜色写在其中。
比如说用红色标记父节点:
\node
[red]{parent}
child {node {child 1}}
child {node {child 2}}
;
再比如说用红色标记左子节点:
\node
{parent}
child [red]{node {child 1}}
child {node {child 2}}
;
可以使用下面代码来调整树中线段的样式,比如实线、虚线等。
默认情况下,线段是实线,但是如果要把上面这个树的右节点的线段从实线换成虚线,那么可以使用下面的语句来实现:
\node
{parent}
child [red] {node {child 1}}
child {node {child 2} edge from parent [dashed]}
;
效果如下:
别看这里很简单,但是支持或可以实现的样式非常非常多,这里细说太冗余了,还请移步:https://tikz.dev/tikz-actions。
绘制内容简单的树状图的时候,一般都会用在节点外围画一个圆,那么可以在父节点类型{parent}
前面或子节点类型名称child
后面加个[]
,在其中加上draw
和要形状等属性信息(如果有的话),从而来为前文绘制的二叉树添加圆圈。如下:
\node
[draw, circle] {parent}
child {node[draw, circle] {child 1}}
child {node[draw, circle] {child 2}}
;
二叉树不可能只有这种基础组成,所以还要来嵌套使用。而嵌套就是在某个子节点中(也就是大括号中{}
),写它的子节点。看看下面的例子你就能懂了:
\node {parent}
child {node {1}}
child {
node {2}
child {node {3}}
child {node {4}}
}
;
可以看到,使用tikz
包画复杂的树很很麻烦,要打一堆node
、child
等词,所以tikz-qtree
进行了改进,使用简单的语法即可画出复杂的树。
首先,LaTeX 文件的代码结构如下:
%自定义类型和格式
\documentclass[10pt]{article}
%导入tikz包和tikz-qtree包(因为后者是基于前者,所以必须两个都导入)
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
%在这里输入绘制树的代码
\end{tikzpicture}
\end{document}
下面演示的所有的代码,除非特殊说明,不然都是放在上述结构中的%在这里输入绘制树的代码
的位置。
tikz-qtree
画一棵树非常简单。
树的开头使用\Tree
表示开始。方括号[
和]
用来划分出子树,句点.
表示子树的根。语句如下(需要注意的是,子树的根节点后面就算没有节点了,但是也要加空格):
\Tree
[.1
[.2 ] [.3 ] [.4 ] [.5 ]
]
tikz-qtree
生成森林的方式和tikz
不一样,因为一个tikzpicture
作用域中只能有一颗树。所以要写在多个tikzpicture
中。如果想水平摆放,可以直接连着写:
%自定义类型和格式
\documentclass[10pt]{article}
%导入tikz包和tikz-qtree包(因为后者是基于前者,所以必须两个都导入)
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
\Tree
[.1
[.2 ] [.3 ] [.4 ] [.5 ]
]
\end{tikzpicture}
\begin{tikzpicture}
\Tree
[.1
[.2 ] [.3 ] [.4 ] [.5 ]
]
\end{tikzpicture}
\end{document}
如果想指定树叶的方向和排列位置,可以在tikzpicture
后面加上[grow=]
或[grow'=]
来指定,参数为up
、down
、left
、right
来表示开口向上下左右方向。
并且这两种参数不太一样,
[grow=]
是逆时针排列子节点;[grow'=]
是顺时针排序子节点。不仅是为了方便理解,还因为这个使用有点特殊。如果想两棵树并排,那需要在两个节点之间使用百分号%
。下面来举几个例子来详细说明一下。
下面语句会生成上下排列、子节点逆时针排列的两个二叉树:
\begin{tikzpicture}[grow'=up]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
\begin{tikzpicture}[grow'=down]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
但是给语句中间加上百分号%
,那就会得到并列的树:
\begin{tikzpicture}[grow'=up]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
%
\begin{tikzpicture}[grow'=down]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
上文已经看到了,绘制二叉树只用很简单的结构即可。.
开头的表示跟节点,下面每个叶节点用方括号[]
包裹起来:
\begin{tikzpicture}
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
没有那么丰富的自定义功能,但是可以支持调整线的粗细、样式等属性。
如果想加粗所有的线和节点,就使用以下语句:
\tikzset{edge from parent/.append style={very thick}}
例如:
\begin{tikzpicture}
\tikzset{edge from parent/.append style={very thick}}
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
虚线的话将[dashed]
加在\begin{tikzpicture}
后面,如下:
\begin{tikzpicture}[dashed]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
如果想带箭头,那么将[semithick,->]
加在\begin{tikzpicture}
后面,如下:
\begin{tikzpicture}[semithick,->]
\Tree
[.1
[.2 ] [.3 ]
]
\end{tikzpicture}
如何加粗节点上一节提到了,使用\tikzset{edge from parent/.append style={very thick}}
,那么如何给节点加圆圈呢?
只能一个个节点加圆圈,使用以下结构和语句:
\begin{tikzpicture}
\Tree
[.1
[.2 ] [.\node[draw, circle]{3}; ]
]
\end{tikzpicture}
tikz-qtree
来绘制复杂的二叉树就很容易了,就是需要注意大括号闭合。
中括号[]
包含每个节点和其子节点。.
表示根节点,后面跟的是其子节点。
\begin{tikzpicture}
\Tree
[.1
[.2 [.3 ] ]
[.4 [5 6 ] ]
]
\end{tikzpicture}
希望能帮到有需要的人~