具有线性面积和任意纵横比的一般树的直线绘制
1. 引言
在图形绘制领域,树的绘制通常要求是平面的,即没有交叉。树的绘制有多种类型,如直线绘制(每条边画成单个直线段)、网格绘制(所有节点具有整数坐标)和平面绘制(边在图中不相交)。我们主要关注网格绘制。矩形的宽度、高度、面积和纵横比分别指其包含的相同坐标网格点数量以及长边与短边的比例,树的绘制的这些属性等于其包围矩形的相应属性。树节点的度是指与之相连的边的数量,树的度是节点的最大度,度为 3 的树是二叉树。
2. 研究成果
通常希望用小面积的平面直线网格绘制树,并让用户控制其纵横比。显然,任何具有 n 个节点的平面网格树绘制都需要 Ω(n) 的面积。一个基本问题是,这个界限是否是紧密的,即能否为具有 n 个节点的树 T 构造一个面积为 O(n) 的平面直线网格绘制。
之前的研究表明,二叉树可以用 O(n) 的面积进行这种绘制。但在实际应用中,度大于 3 的树很常见,因此一个自然的问题是,这个结果能否推广到更高度的树。本文给出了部分答案,提供了一种算法,能在 O(n log n) 时间内为度为 O(nδ)(其中 δ < 1/2 是常数)的 n 节点树构造一个面积为 O(n) 的平面直线网格绘制。而且,该绘制的纵横比可以参数化,对于任何常数 α(0 ≤ α < 1),算法可以构造出纵横比在 [1, nα] 范围内的绘制。
之前,一般树的平面直线网格绘制的最佳已知面积界限是 O(n log n),可以通过对 HV 绘制算法的简单修改来实现。也有研究探讨了二叉树的平面直线网格绘制的纵横比和面积之间的关系。
3. 预备知识
-
树的相关定义
:
- 度为 d 的树 T 有一个特殊节点 v,它最多有 d - 2 个孩子,v 称为 T 的链接节点。
- 若每个节点的孩子被分配了从左到右的顺序,则 T 是有序树。
- T 的部分树是 T 的连通子图。
- 若 T 是有序树,其最左路径 p 是由最左孩子节点组成的最大路径(除第一个节点是根节点),p 的最后一个节点称为 T 的最左节点。
- 节点 v 的兄弟节点是与 v 有相同父节点的节点。若 T 没有节点,则它是空树。
-
绘制的相关定义
:
- 绘制 Γ 是树 T 的平面直线网格绘制。
- 矩形 R 包含 Γ,若其纵横比在 [1, nα](0 ≤ α < 1)范围内,则称 R 具有良好的纵横比。
-
设 r 是 T 的根,u∗ 是 T 的链接节点,若 Γ 满足以下三个属性,则它是 T 的可行绘制:
- 属性 1:根 r 位于 Γ 的左上角。
- 属性 2:若 u∗ ≠ r,则 u∗ 位于 Γ 的底部边界,且可以在其垂直通道中向下移动任意距离而不导致边交叉。
- 属性 3:若 u∗ = r,则 T 的其他节点或边不会位于或穿过 r 占用的垂直和水平通道。
-
定理
:
- 定理 1:设 n0 和 α 是两个常数(n0 ≥ 1 且 0 < α < 1/2),m1, m2, …, mn0 是一组正数,G(n) 和 g(n) 是两个函数,满足特定条件,则若 g(n) ≤ cnβ(c > 0 和 β 是常数且 0 ≤ β < 1/2),则 G(n) = O(n)。
- 定理 2:在任何度为 d 的树 T 中,存在一个节点 u,移除 u 及其关联边可将 T 最多拆分为 d 棵树,每棵树最多有 (2/3)n 个节点(n ≥ 2 是 T 的节点数),节点 u 称为 T 的分隔符,且可以在 O(n) 时间内找到。
4. 算法 u∗ - HV - Draw
该算法用于构造具有链接节点 u∗ 的树 T 在足够大的矩形 R 内的可行绘制,基于著名的 HV - Drawing 算法,该算法最初为二叉树定义,但可轻松扩展到更高度的树。
算法步骤如下:
1. 对每个节点的孩子进行排序,使 u∗ 成为 T 的最左节点。
2. 设 r = r1, r2, …, rk - 1, rk = u∗ 是 T 的最左路径上的节点,cij 是 rj 的其他孩子,Tij 是以 cij 为根的子树,nij 是 Tij 的节点数。
3. 若 W ≤ H(或 H < W),对于每个 j(1 ≤ j ≤ k),使用 HV - Drawing 算法在矩形 Rij 内构造 Tij 的绘制,Rij 的高度(或宽度)为 nij,宽度(或高度)为 log2 nij + 2。
4. 根据 W 和 H 的大小关系,将 Tij 的绘制进行堆叠或左右排列,得到 T 的绘制。
引理表明,对于具有链接节点 u∗ 的 n 节点度为 d 的树 T,u∗ - HV - Draw 算法可以在 O(n) 时间内,在宽度为 n 高度为 log2 n + 4 或宽度为 log2 n + 4 高度为 n 的矩形内构造出可行绘制。
以下是该算法的流程图:
graph TD;
A[开始] --> B[排序孩子节点使 u*为最左节点];
B --> C[确定最左路径节点及子树信息];
C --> D{W ≤ H?};
D -- 是 --> E[按 W ≤ H 构造子树绘制];
D -- 否 --> F[按 H < W 构造子树绘制];
E --> G[堆叠子树绘制];
F --> H[左右排列子树绘制];
G --> I[结束];
H --> I;
5. 整体树绘制算法
设 T 是具有链接节点 u∗ 的度为 d 的树(d = O(nδ),δ < 1/2),n 是节点数。设 A 和 ϵ 是两个数,(2δ + 1)/(3 - 2δ) < ϵ < 1,A 在 [1, nϵ] 范围内,R 是具有纵横比 A、宽度 W 和高度 H 的足够大矩形。
我们的树绘制算法 DrawTree 使用分治法递归地在 R 内构造 T 的可行绘制 Γ,每个递归步骤执行以下操作:
-
拆分树
:通过移除最多两个节点及其关联边,将 T 最多拆分为 2d - 1 个部分树,每个部分树最多有 2/3n 个节点。根据分隔符节点 u 是否在最左路径上,分为两种情况:
-
情况 1:u 不在最左路径上
:有七个子情况,一般情况和六个特殊情况。移除节点 a 和 u 及其关联边,将 T 拆分为最多 2d - 1 个部分树 TA、TC、Tβ、T′1, …, T′i(0 ≤ i ≤ d - 3)和 T1, …, Tj(0 ≤ j ≤ d - 1),并指定相应的链接节点。
-
情况 2:u 在最左路径上
:有四个子情况和五个特殊情况。移除节点 u 及其关联边,将 T 拆分为最多 d 个部分树 TA、TC 和 T1, …, Tj(0 ≤ j ≤ d - 2),并指定相应的链接节点。
-
分配矩形
:相应地将 R 最多拆分为 2d - 1 个较小的矩形,并将每个小矩形分配给一个部分树。分割通过切割 R 的长边进行。设 Tk 是 T 的部分树,nk 是其节点数,W 和 H 是 R 的宽度和高度,假设 H < W(W ≤ H 情况类似处理),H′ = H - 2,W′ = W - (2d - 1) max{(2n)(1 - ϵ)/(1 + ϵ), log2 n + 4} - 2,x = nk/n。若 nk < H′(即 Tk 是非常小的树),则 Wk = log2 nk + 4,Hk = H′。
-
绘制部分树
:递归地在分配的矩形内构造每个部分树的可行绘制。
-
组合绘制
:在 R 内排列部分树的绘制,并绘制从 T 中移除的节点和边,使得到的 T 的绘制 Γ 是可行绘制。
以下是 DrawTree 算法的步骤总结表格:
| 步骤 | 操作 |
| ---- | ---- |
| 拆分树 | 移除最多两个节点及边,分两种情况拆分为部分树 |
| 分配矩形 | 根据部分树节点数分配矩形 |
| 绘制部分树 | 递归绘制部分树 |
| 组合绘制 | 排列部分树绘制并绘制移除部分 |
以下是 DrawTree 算法的流程图:
graph TD;
A[开始] --> B[拆分树];
B --> C[分配矩形];
C --> D[绘制部分树];
D --> E[组合绘制];
E --> F[结束];
具有线性面积和任意纵横比的一般树的直线绘制
5.1 拆分树详细说明
拆分树 T 为部分树的具体操作如下:
1. 对每个节点的孩子进行排序,让 u∗ 成为 T 的最左节点。
2. 利用定理 2 找出 T 的分隔符节点 u。
3. 根据 u 是否在最左路径上,分为两种情况:
-
情况 1:u 不在最左路径上
-
一般情况
:树 T 具有如图 2(a) 所示的形式。在图中,r 是 T 的根,c1, …, cj 是 u 的孩子,T1, …, Tj 是以 c1, …, cj 为根的树,0 ≤ j ≤ d - 1,Tα 是以 u 为根的子树,w 是 u 的父节点,a 是路径 r 到 v 和 T 的最左路径的最后公共节点,f 是 a 的包含在路径 r 到 v 中的孩子,Tβ 是以 f 为根且包含 w 但不包含 u 的最大树,TB 由 Tα 和 Tβ 以及边 (w, u) 组成,e 是 a 的父节点,g 是 a 的最左孩子,TA 是以 r 为根且包含 e 但不包含 a 的最大树,TC 是以 g 为根的树,b1, …, bi 是 f 和 g 的兄弟节点,T′1, …, T′i 是以 b1, …, bi 为根的树,0 ≤ i ≤ d - 3。
-
特殊情况
:有六种特殊情况,分别是 (b) TA = ∅, TC = ∅, 0 ≤ i ≤ d - 3;(c) TA ≠ ∅, TC ≠ ∅, g = u∗, 0 ≤ i ≤ d - 3;(d) TA ≠ ∅, TC = ∅, r ≠ e, 0 ≤ i ≤ d - 3;(e) TA ≠ ∅, TC = ∅, r = e, 0 ≤ i ≤ d - 3;(f) TA = ∅, TC ≠ ∅, g ≠ u∗, 0 ≤ i ≤ d - 3;(g) TA = ∅, TC ≠ ∅, g = u∗, 0 ≤ i ≤ d - 3。在每种情况中,移除节点 a 和 u 及其关联边,将 T 拆分为最多 2d - 1 个部分树 TA、TC、Tβ、T′1, …, T′i(0 ≤ i ≤ d - 3)和 T1, …, Tj(0 ≤ j ≤ d - 1)。同时指定 e 为 TA 的链接节点,w 为 Tβ 的链接节点,u∗ 为 TC 的链接节点,随机选择 T′i(0 ≤ i ≤ d - 3)的一个叶子节点 ei 和 Tj(0 ≤ j ≤ d - 1)的一个叶子节点 ej,分别指定为 T′i 和 Tj 的链接节点。
-
情况 2:u 在最左路径上
-
一般情况
:树 T 具有如图 3(a) 所示的形式。在图中,r 是 T 的根,c1, …, cj 是 v 的兄弟节点,T1, …, Tj 是以 c1, …, cj 为根的树,1 ≤ j ≤ d - 2,e 是 u 的父节点,TA 是以 r 为根且包含 e 但不包含 u 的最大树,TC 是以 u 的孩子 v 为根的树。
-
特殊情况
:有五种特殊情况,分别是 (b) TA = ∅, TC ≠ ∅, 且 j = 0;(c) TA = ∅, TC ≠ ∅, 且 1 ≤ j ≤ d - 2;(d) TA ≠ ∅, TC ≠ ∅, 且 j = 0;(e) TA = ∅, TC = ∅, 且 1 ≤ j ≤ d - 2;(f) TA ≠ ∅, TC = ∅, 且 1 ≤ j ≤ d - 2。在每种情况中,移除节点 u 及其关联边,将 T 拆分为最多 d 个部分树 TA、TC 和 T1, …, Tj(0 ≤ j ≤ d - 2)。指定 e 为 TA 的链接节点,u∗ 为 TC 的链接节点,随机选择 Tj 的一个叶子节点 ej 并指定为 Tj 的链接节点。
以下是两种情况的对比表格:
| 情况 | 分隔符位置 | 拆分方式 | 部分树数量 | 链接节点指定 |
| ---- | ---- | ---- | ---- | ---- |
| 情况 1 | 不在最左路径 | 移除 a 和 u 及边 | 最多 2d - 1 个 | e 为 TA,w 为 Tβ,u∗ 为 TC,随机选叶子为 T′i 和 Tj |
| 情况 2 | 在最左路径 | 移除 u 及边 | 最多 d 个 | e 为 TA,u∗ 为 TC,随机选叶子为 Tj |
5.2 分配矩形详细说明
设 Tk 是 T 的部分树,对于情况 1,Tk 可以是 TA、TC、Tβ、T′1, …, T′i(0 ≤ i ≤ d - 3)或 T1, …, Tj(0 ≤ j ≤ d - 1);对于情况 2,Tk 可以是 TA、TC 或 T1, …, Tj(0 ≤ j ≤ d - 2)。设 nk 是 Tk 的节点数,算法 DrawTree 为 Tk 分配一个矩形 Rk,其宽度 Wk 和高度 Hk 确定方式如下:
1. 设 W 和 H 分别是 R 的宽度和高度,假设 H < W(W ≤ H 的情况处理方式类似)。
2. 计算 H′ = H - 2,W′ = W - (2d - 1) max{(2n)(1 - ϵ)/(1 + ϵ), log2 n + 4} - 2,x = nk/n。
3.
判断 Tk 大小
:
- 若 nk < H′(即 Tk 是非常小的树),则 Wk = log2 nk + 4,Hk = H′。
以下是分配矩形的步骤列表:
1. 获取 R 的宽高 W 和 H。
2. 假设 H < W,计算 H′ 和 W′。
3. 计算 x = nk/n。
4. 判断 nk 与 H′ 的大小关系,确定 Wk 和 Hk。
5.3 绘制部分树和组合绘制
- 绘制部分树 :在分配好矩形后,递归地在每个分配的矩形内构造部分树的可行绘制。这个过程会不断地调用 DrawTree 算法,直到部分树足够小,可以直接使用 u∗ - HV - Draw 算法进行绘制。
- 组合绘制 :在矩形 R 内,根据拆分树时的不同情况(图 2 和图 3 所示)来排列部分树的绘制。然后绘制从 T 中移除的节点和边,使得最终得到的树 T 的绘制 Γ 是可行绘制。具体的排列方式会根据树的结构和矩形的大小关系(W ≤ H 或 H < W)有所不同。
总结
本文围绕具有线性面积和任意纵横比的一般树的直线绘制展开研究。通过对树的绘制问题的探讨,提出了一种新的算法 DrawTree,结合 u∗ - HV - Draw 算法,能够在一定条件下为度为 O(nδ)(δ < 1/2)的树构造面积为 O(n) 且纵横比可参数化的平面直线网格绘制。该算法采用分治法,通过拆分树、分配矩形、绘制部分树和组合绘制等步骤,有效地解决了一般树的绘制问题。未来,可进一步研究如何优化算法的时间复杂度,以及将该算法应用到更多实际场景中。
以下是整个算法流程的总结流程图:
graph TD;
A[开始] --> B[算法 u* - HV - Draw 准备]
B --> C[DrawTree 算法启动]
C --> D[拆分树]
D --> E[分配矩形]
E --> F[绘制部分树]
F --> G[组合绘制]
G --> H[结束]
在实际应用中,可根据具体的树结构和需求,灵活调整算法参数,以获得更好的绘制效果。例如,对于不同度的树,可以选择合适的 δ 值来平衡算法的复杂度和绘制效果。同时,对于纵横比的选择,可以根据展示需求进行调整,以满足不同的视觉要求。
超级会员免费看
7137

被折叠的 条评论
为什么被折叠?



