平衡二叉树可视化算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

摘要:二叉树是一种重要的数据结构,树结点按照一定关系存储而构成的二叉查找树因其搜索效率很高而被广泛应用。但二叉树的实现主要是基于二叉链表形式在内存中进行数据组织,对于各结点间的父子关系不方便观察。因此本文提出一种算法以最大的绘图空间利用率对二叉树进行可视化实现,对于程序调试时的结点关系查看和教学演示都有很好的实用价值。

1.引言

二叉查找树是一种数据结构,它支持多种动态集合操作,在二叉查找树上执行的基本操作与树的高度成正比。对于一棵含n个结点的完全二叉树这些操作的最坏情况运行时间为O(log2n)。但是,如果树是含有n个结点的线性链,则这些操作的最坏情况运行时间为Θ(n)。

对二叉查找树进行一些变形,可以避免二叉查找树的严重不平衡现象,如平衡二叉树、红黑树等。

上述数据结构一般以二叉链表的形式进行实现,数据主要存储在内存中以便搜索。但是对于某些有限制条件的二叉树(如红黑树)来说,在程序实现后的调试过程中,如果没有一个可视化的显示方法,要确定所建立的树结构是否满足所有限制条件是很不方便的。此外,对于数据结构的教学过程中,如果能够以图形化的方式来表示结构的建立过程,则更加直观易懂。

因此,实现二叉树的可视化具有重要意义。参考文献[1]实现了一种二叉树的可视化算法,但该算法是基于完全二叉树的结构进行结点布局的,当某些子树缺失时,这种表示方法对空间浪费较大。

本文实现了一种更有效的算法,可以在有限的平面绘图空间内绘制更多的结点,让结点排列更紧凑。

2.二叉查找树基本结构描述

最简单的二叉查找树结点结构如下,

struct node {

int key; /*关键字域*/

struct node *parent; /*指向父节点指针*/

struct node *left; /*指向左子结点指针*/

struct node *right; /*指向右子结点指针*/

}

如上结点结构所构成的二叉查找树不能避免树的不平衡问题,在结点中增加数据域并定义一些平衡化处理方法后可以保证二叉查找树总是会处于一种平衡的或近乎平衡的状态,其中红黑树就是一种近乎平衡的二叉查找树。红黑树的结点结构中增加了一个结点颜色域(color),其结构如下,

struct node {

int key; /*关键字域*/

color_type color; /*结点颜色,非红即黑*/

struct node *parent; /*指向父节点指针*/

struct node *left; /*指向左子结点指针*/

struct node *right; /*指向右子结点指针*/

}

红黑树需要保证以下红黑性质:(1)每个结点是红的,或者是黑的。(2)根结点是黑的。(3)每个叶节点是黑的。(4)如果一个结点是红的,则它的两个子结点是黑的。(5)对每个结点,从该节点到其子孙结点的所有路径上包含相同数目的黑结点。

为了满足以上性质,红黑树定义了额外的“旋转”操作,即左旋操作和右旋操作,当树结构不满足如上的红黑性质时,通过旋转操作可保持红黑树的近乎平衡性,而平衡二叉树(AVL)同样是基于这两种额外操作来保持树的平衡的。

由于红黑树应用广泛,且操作相对复杂,其操作集合是另外两种二叉树的超级,所以本文针对红黑树实现其可视化算法。为了树的可视化实现,在红黑树种增加几个数据域,形成如下的结点结构,

struct node {

int key; /*关键字域*/

color_type color; /*结点颜色,非红即黑*/

int left_offset; /*该结点距其左子树根结点的单位水平距离数*/

int right_offset; /*该结点距其右子树根结点的单位水平距离数*/

int total_left_offset; /*该结点距其左子树最左结点的单位水平距离数*/

int total_right_offset; /*该结点距其右子树最右结点的单位水平距离数*/

struct node *parent; /*指向父节点指针*/

struct node *left; /*指向左子结点指针*/

struct node *right; /*指向右子结点指针*/

} 由上述结构可知主要增加了四个水平距离域。现定义水平距离如下:一个单位的水平距离等于叶节点与其父节点的连线在水平方向的投影距离,如图(1)中的距离d 为一个单位的水平距离。

图(1) 水平距离定义

另外,为了处理代码中的边界条件,在红黑树中增加了一个哨兵结点,在此不妨设其名称为nil ,所有结点如果没有左、右子树,则相应left 、right 域均指向该nil 结点。在绘图时,nil 结点不必绘制。

3. 二叉树可视化算法描述

3.1 算法基本原理

本算法的目的是使某一子树的根结点与其父节点的分支连线在水平方向的投影距离最小,为了说明算法的原理,采用以下两步进行阐述。

(1) 当结点是叶节点时,其left 、right 域指向nil 结点,则叶节点到其

左右子树的根结点的最短水平距离各为1,如图(2)所示。

图(2) 叶结点offset 域 (2) 当结点A 是非叶子结点时,A 到其左(右)子树的根结点B 的最

短水平距离等于B 到该子树的最右(左)nil

结点间的水平距离。

1

此时B的最右(左)nil结点与A在同一条垂直线上。而假设B有

右子树,其根结点为C,则B到其最右nil结点的距离等于C到其

最左nil结点与C到其最右nil结点的距离和。如图(3)所示。

C->total_left_offset C->total_right_offset

图(3)非叶结点offset域

到此为止,可以给出新增加的四个offset域的定义式:

nil->total_left_offset = nil->total_right_offset = 1 (1)

nil->right_offset = nil->left_offset = 0 (2)

x->right_offset = x->right->total_left_offset (3)

x->left_offset = x->left->total_right_offset (4)

x->total_right_offset = x->right->total_left_offset + x->right->total_right_offset

(5)

x->total_left_offset = x->left->total_left_offset + x->left->total_right_offset

(6)

其中结点x为非哨兵(nil)结点。

改变二叉树结构的操作过程(插入和删除)最终都转换到了对叶节点的操作,而由(1)~(6)式可看出一个结点的左(右)offset域其实是由其左(右)子树所包含的叶节点个数决定的,因此,可以设计算法在增加或删除了一个叶节点后再由此到根结点上溯进行各相关结点offset域的更新。

3.2算法实现

针对红黑树的操作中涉及到叶节点数量变化的主要是插入和删除操作,在这两种操作中包含了一个辅助的旋转操作过程,因此,主要分析在上述三种操作时各offset域的变化。

3.2.1 红黑树结点的插入操作

相关文档
最新文档